django - Ionic Google 社交身份验证到 Django Rest Framework 后端

标签 django cordova ionic-framework python-social-auth django-rest-framework

我正在尝试让社交身份验证适用于我的移动应用程序(Android 上的 Ionic 应用程序)。 Django Rest 框架后端,包含 rest_framework_jwtsocial_djangorest_social_auth

在我的 Ionic 应用程序上,我使用 satellizer.js但是,我无法使用 InAppBrowser,所以现在我尝试使用 cordova-plugin-googleplus 执行以下操作:

第 1 步 (在客户端/应用程序上)

if (provider == 'google') {
    // Use Google API Natively to get tokens and user info  
    window.plugins.googleplus.login(
                {
                    // TODO Get the WebClient from App settings
                  'webClientId': '[*.myclientid]', // optional clientId of your Web application from Credentials settings of your project - On Android, this MUST be included to get an idToken. On iOS, it is not required.
                  'offline': true, // optional, but requires the webClientId - if set to true the plugin will also return a serverAuthCode, which can be used to grant offline access to a non-Google server
                }) ................

结果: 这会为我提供包含 idTokenserverAuthCodeuserId 的有效响应。

步骤#2

我不确定下一步是什么。最初,我打算尝试使用 Django rest_social_auth 从我的客户端/应用程序执行以下操作:

POST /api/login/social/

带有数据(json)

provider=google&code=ASLKDJASLDKJASLD

它应该返回 JWT token ( from my understanding of the docs ),但是,它没有传递 JWTAuthMixin因为调用 get_authorization_header(request).split() 没有返回值在那个 Mixin 中。这意味着除了 400 错误之外,不会向我的客户端/应用程序返回任何内容。

在传递我的 idToken 或 serverAuthCode 时,我是否应该在 Ionic 应用程序 POST 中添加 header ?或者我是否走错了方向......

此身份验证流程有任何实现建议吗?

最佳答案

到目前为止,我做了以下工作并且有效。

<强>1。在应用程序/客户端上

(客户端使用 satellizer.jscordova-plugin-googleplus)

if (provider == 'google') {
            // Use Google API Natively to get tokens and user info  
            window.plugins.googleplus.login(
                    {
                        // TODO Get the WebClient from 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);
                            /.. Do something ../
                          })
                          .error(function(data){
                             console.log("There was an error" + JSON.stringify(data)); 
                          });                       
                    },
                    function (msg) {
                        // TODO Set Error states
                        console.error('error: ' + msg);
                    }

                );
        }

摘要

  • 应用调用 Google plus API googleplus.login方法(发送我的 webClientId)
  • 我在登录 Django 后端后发布了从 google 获得的 idToken 和 serverAuthCode。

<强>2。我的后端方法

网址

我的应用程序/客户端点击 url(r'^[MY BACKEND URL]/(?P<backend>[\w-]+)/$', ObtainAuthToken.as_view(), ),

查看

这会调用以下 View 和函数:

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 and server_auth_code and verify_google_user_token_ID(user_tokenID):

            # Get Google OAuth credentials for the verified GOOGLE user.
            credentials = settings.GOOGLE_FLOW.step2_exchange(server_auth_code)

            # Here we call PSA to authenticate like we would if we used PSA on server side.
            user = register_by_access_token(request, backend, token=credentials.access_token)

            # If user is active we get or create the REST token and send it back with user data
            if user and user.is_active:
                # Generate JWT token for user and pass back to 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 the Access Token and/or the 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 the 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 as 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。返回客户端

然后,我的客户端查看响应并获取返回的 JWT 并将其加载到内存中 $auth.setToken(data.jwt_token);

我认为这目前有效,但我仍然需要处理 token 刷新和撤销等问题。

关于django - Ionic Google 社交身份验证到 Django Rest Framework 后端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46208584/

相关文章:

django - 字段 'id'应该有一个数字,但在Django中导入数据时却得到 'ANPKUR0724'

python - Django 根据用户输入查询数据库

android - 移动共享对话框上的 Facebook 共享按钮被切掉

javascript - 文件传输 onprogress 不起作用 - PhoneGap 3.5.0

html - 如何将按钮与 ionic 中的图标对齐

Angular2Firebase 通过多个值查询 whereIN

python - 无法使用 Django Haystack : 'Connection refused' 重建索引 elasticsearch

python - Django 管理性能问题

ios - Phonegap Plugman iOS - 错误 : Plugin not found

angular - 在 ionic 搜索栏上输入验证?