cordova - Ionic Google social authentication to Django Rest Framework backend -
i trying social authentication working mobile app (an ionic app on android). django rest framework backend rest_framework_jwt, social_django, , rest_social_auth.
on ionic app using satellizer.js, however, can't use inappbrowser trying following cordova-plugin-googleplus:
step#1 (on client/app)
if (provider == 'google') { // use google api natively tokens , user info window.plugins.googleplus.login( { // todo webclient app settings 'webclientid': '[*.myclientid]', // optional clientid of web application credentials settings of project - on android, must included idtoken. on ios, not required. 'offline': true, // optional, requires webclientid - if set true plugin return serverauthcode, can used grant offline access non-google server }) ................
result: gets me valid response both idtoken, serverauthcode, , userid.
step#2
i not sure next step is. originally, going try using django rest_social_auth following client/app:
post /api/login/social/
with data (json)
provider=google&code=aslkdjasldkjasld
which supposed return jwt token (from understanding of docs), however, not passing jwtauthmixin
there no value returned call get_authorization_header(request).split()
in mixin. these means nothing returned client/app except 400 error.
am supposed adding header ionic app post when passing idtoken or serverauthcode? or on wrong side of tracks...
are there implementation recommendations auth flow?
so far did following , works.
1. on app/client
(the client uses satellizer.js , cordova-plugin-googleplus)
if (provider == 'google') { // use google api natively tokens , user info window.plugins.googleplus.login( { // todo webclient app settings 'webclientid': '*[googleclientid]*.apps.googleusercontent.com', 'offline': true }, function (obj) { $http.post(server.url + '[my backend url]' + '/google-oauth2/', {code: obj.idtoken, servauthcode: obj.serverauthcode}) .success(function(data){ $auth.settoken(data.jwt_token); /.. ../ }) .error(function(data){ console.log("there error" + json.stringify(data)); }); }, function (msg) { // todo set error states console.error('error: ' + msg); } ); }
summary
- the app calls google plus api
googleplus.login
method (sending webclientid) - i post resulting idtoken , serverauthcode obtained google after login django backend.
2. backend methods
url
my app/client hits url(r'^[my backend url]/(?p<backend>[\w-]+)/$', obtainauthtoken.as_view(), ),
view
this calls following view , functions:
class obtainauthtoken(apiview): permission_classes = (allowany,) def post(self, request, backend): data = request.data user_tokenid = data['code'] server_auth_code = data['servauthcode'] if user_tokenid , server_auth_code , verify_google_user_token_id(user_tokenid): # google oauth credentials verified google user. credentials = settings.google_flow.step2_exchange(server_auth_code) # here call psa authenticate if used psa on server side. user = register_by_access_token(request, backend, token=credentials.access_token) # if user active or create rest token , send user data if user , user.is_active: # generate jwt token user , pass client jwt_payload_handler = api_settings.jwt_payload_handler jwt_encode_handler = api_settings.jwt_encode_handler payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) return jsonresponse({'id': user.id, 'name': user.username, 'jwt_token': token}) return jsonresponse({'status':'false','error':'bad credentials, check access token and/or uid'}, status=403) def verify_google_user_token_id(user_tokenid): try: google_http_request = google.auth.transport.requests.request() idinfo = verify_token(user_tokenid, request=google_http_request, audience=settings.social_auth_google_oauth2_full_key) # or, if multiple clients access backend server: if idinfo['aud'] not in [settings.google_app_id_android, settings.google_app_id_web]: raise crypt.appidentityerror("unrecognized client.") if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: raise crypt.appidentityerror("wrong issuer.") return true except crypt.appidentityerror e: # invalid token return false @psa('social:complete') def register_by_access_token(request, backend, token): backend = social_core.backends.google.googleoauth2() user = backend.do_auth(access_token=token, backend=backend) if user: return user else: return none
3. on client
my client looks @ response , takes returned jwt , loads memory $auth.settoken(data.jwt_token);
i think works now, still have deal token refresh , revocation etc.
Comments
Post a Comment