Django Oauth 工具包:用户数据自省 [英] Django Oauth Toolkit: User data over introspection

查看:56
本文介绍了Django Oauth 工具包:用户数据自省的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前情景:

我正在使用 Introspect 来验证身份验证服务器上的访问令牌.此调用仅从身份验证服务器返回用户的用户名"并将其保存在资源服务器中.认证服务器和资源服务器上同一用户的Id不一定相同.

I'm using Introspect to validate access token on the authentication server. This call returns only 'username' of the user from the authentication server and saves it in the resource server. The Id of the same user on the authentication server and the resource server are no necessarily the same.

预期场景:

我想接收有关用户的更多数据(电子邮件、电话号码、地址等)并将其保存在资源服务器中.

I want to receive more data about the user (email, phone number, address, etc..) and save it in the resource server.

到目前为止我做了什么:

我修改了 django-oauth-toolkit/oauth2_provider/views/introspect.py/get_token_response 以返回我需要的数据.

I modified the django-oauth-toolkit/oauth2_provider/views/introspect.py/ get_token_response to return the data I need.

剩下的:

如何将这些数据保存在资源服务器中?还是在我需要用户数据时对身份验证服务器进行 api 调用更好?

How do I save those data in the resource server? or is it better to make an api call to the authentication server whenever I require the user data?

推荐答案

我通过修改 Auth-Server 中 IntrospectTokenView 中的 get_token_response 来实现这一点

I achieved this by modifying get_token_response in IntrospectTokenView in the Auth-Server

def get_token_response(token_value=None):
        try:
            token = get_access_token_model().objects.select_related(
                "user", "application"
                ).get(token=token_value)
        except ObjectDoesNotExist:
            return HttpResponse(
                content=json.dumps({"active": False}),
                status=401,
                content_type="application/json"
            )
        else:
            if token.is_valid():
                data = {
                    "active": True,
                    "scope": token.scope,
                    "exp": int(calendar.timegm(token.expires.timetuple())),
                }
                if token.application:
                    data["client_id"] = token.application.client_id
                if token.user:
                    data["username"] = token.user.get_username()
# TODO: DANGER ZONE
# Pass extra parameters
# ------------------------------------------------------------------------------
                    data["email"] = token.user.email
                    data["phone_number"] = token.user.phone_number
                    data["is_company"] = token.user.is_company
                    customer = token.user.customer
                    data["designation"] = customer.designation
                    company = customer.company
                    data["company"] = company.company_name
# ------------------------------------------------------------------------------
                return HttpResponse(content=json.dumps(data), status=200, content_type="application/json")
            else:
                return HttpResponse(content=json.dumps({
                    "active": False,
                }), status=200, content_type="application/json")

和资源服务器中OAuth2Validator中的_get_token_from_authentication_server

and _get_token_from_authentication_server in OAuth2Validator in the Resource-Server

def _get_token_from_authentication_server(
            self, token, introspection_url, introspection_token, introspection_credentials
    ):
        headers = None
        if introspection_token:
            headers = {"Authorization": "Bearer {}".format(introspection_token)}
        elif introspection_credentials:
            client_id = introspection_credentials[0].encode("utf-8")
            client_secret = introspection_credentials[1].encode("utf-8")
            basic_auth = base64.b64encode(client_id + b":" + client_secret)
            headers = {"Authorization": "Basic {}".format(basic_auth.decode("utf-8"))}

        try:
            response = requests.post(
                introspection_url,
                data={"token": token}, headers=headers
            )
        except requests.exceptions.RequestException:
            log.exception("Introspection: Failed POST to %r in token lookup", introspection_url)
            return None

        # Log an exception when response from auth server is not successful
        if response.status_code != http.client.OK:
            log.exception("Introspection: Failed to get a valid response "
                          "from authentication server. Status code: {}, "
                          "Reason: {}.".format(response.status_code,
                                               response.reason))
            return None

        try:
            content = response.json()
        except ValueError:
            log.exception("Introspection: Failed to parse response as json")
            return None

        if "active" in content and content["active"] is True:
            if "username" in content:
                user, _created = UserModel.objects.get_or_create(
                    **{UserModel.USERNAME_FIELD: content["username"]}
                )
# TODO: DANGER ZONE
# Adding extra data to user profile and create company
# ------------------------------------------------------------------------------
                user.email = content["email"]
                user.phone_number = content["phone_number"]
                user.is_company = content["is_company"]

                customer, _created_customer = CustomerModel.objects.get_or_create(
                    user = user
                )
                customer.designation = content["designation"]

                company, _created_company = CompanyModel.objects.get_or_create(
                    company_name = content["company"]
                )
                customer.company = company

                customer.save()
                user.save()
# ------------------------------------------------------------------------------
            else:
                user = None

            max_caching_time = datetime.now() + timedelta(
                seconds=oauth2_settings.RESOURCE_SERVER_TOKEN_CACHING_SECONDS
            )

            if "exp" in content:
                expires = datetime.utcfromtimestamp(content["exp"])
                if expires > max_caching_time:
                    expires = max_caching_time
            else:
                expires = max_caching_time

            scope = content.get("scope", "")
            expires = make_aware(expires)

            access_token, _created = AccessToken.objects.update_or_create(
                token=token,
                defaults={
                    "user": user,
                    "application": None,
                    "scope": scope,
                    "expires": expires,
                })

            return access_token

.现在我想知道如何扩展类并添加额外的代码而不是直接修改源代码?感谢您的帮助.

. Now I'm wondering how can I extend the classes and add the extra codes instead of directly modifying the source code? Appreciate any help.

这篇关于Django Oauth 工具包:用户数据自省的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆