【问题标题】:Passing token to the client将令牌传递给客户端
【发布时间】:2015-09-16 11:24:53
【问题描述】:

我正在开发一个 iOS 应用程序并使用 Django 作为后端。我在 Django 中使用了两个应用程序

  • Django OAuth Toolkit支持OAuth认证
  • Python Social Auth支持社交认证

社会认证过程应该是:

  1. GET localhost/login/{应用程序}
  2. 应用程序站点上的身份验证
  3. 重定向到 localhost/complete/{application}
  4. 获取 {application} 的访问令牌
  5. 使用我服务器的访问令牌创建一个新用户,并将其与 {application} 的访问令牌相关联
  6. 重定向到 localhost/accounts/profile

然后,我可以使用服务器的访问令牌与 {application} 进行通信。

但是客户端会看到浏览器以 localhost/login/{application} 开头并以 localhost/accounts/profile 结尾,仍然不知道我的服务器的访问令牌是什么,所以我的问题是如何通过访问令牌到客户端?

一种解决方案是使用访问令牌作为 localhost/accounts/profile?token=MyServerToken 进行重定向,但是如何在重定向到配置文件 url 时添加参数?

【问题讨论】:

  • 客户端打算如何处理服务器的访问令牌?
  • 我将使用服务器的访问令牌来请求数据,如果数据在 {application} 上,我的服务器将使用 {application} 的访问令牌来请求数据,并返回给客户端。

标签: python django authentication oauth python-social-auth


【解决方案1】:

您可能已经在 Django 会话中为您的用户提供了所需的内容。也就是说,如果您使用会话中间件(如果没有它,这种类型的身份验证几乎是不可能的),您的身份提供者特定令牌通常将填充到相关特定提供者的SocialUser 模型上的extra_data 字典中。

例如,假设您引用了 Django 用户模型(我们称之为user):

access_token = user.social_auth.get(provider='google-oauth2').extra_data['access_token']

很遗憾,具体情况会因您使用的后端而异。请记住,这些工具旨在让用户对您的应用进行身份验证,而不是让您对各种身份提供者公开的产品特定 API 执行任意操作。

至于将这些令牌传递给客户端,我需要更多地了解您的用例。有问题的身份提供者可能会在其身份验证流程期间在客户端上设置一些会话 cookie。例如,如果您使用 Facebook 登录,他们会设置一些 cookie,这些 cookie 会由 Facebook 客户端 JavaScript API 自动检索。因此,服务器和客户端之间不需要明确共享令牌。

否则,如果您必须自己做,请将它们存储在安全会话 cookie 中,如下所示:

response.set_cookie(social_auth_tokens,
    value=your_data_here,
    max_age=None, #cookie will expire at end of user session
    expires=None,
    path='/',
    domain=None, #only readable by this domain
    secure=True, #only transmitted over https
    httponly=False) #readable by scripts running on the page

【讨论】:

    【解决方案2】:

    您不应在查询字符串中传递访问令牌,例如/?token=my_token。这不是一种安全的方式,绝对不推荐。

    您可以使用的其他一些方法是:

    方法 1:在响应标头中设置 server_access_token

    您可以在响应标头中设置访问令牌并使用 HTTPS 协议发送。

    令牌将被发送一次并由客户端使用。由于后续请求中不会传递响应头,因此令牌只会传递给客户端一次。然后,客户端将通过在请求标头中设置令牌来使用它来发出进一步的请求。

    class MySocialApplicationRedirectView(View):
    
        def get(self, request, *args, **kwargs):  
            # Here, write your code to fetch the  {application}'s access token, 
            # creating a new user with your server's access token, and then
            # associating it with {application}'s access token
    
            # assign the response to a variable and set the access token as a header in the response 
            response = HttpResponseRedirect('/accounts/profile/')       
            response['X-Auth-Token'] = 'my_server_access_token'    
    
            # can also use the below name as 'X-' prefixed headers are deprecated     
            # response['Auth-Token'] = 'my_server_access_token'
    
            return response 
    

    然后,客户端可以从标头中检索令牌并使用此令牌发出进一步的请求。在进一步的请求中,他必须在请求标头中发送访问令牌。

    方法 2:将 server_access_token 设置为 cookie

    另一种选择是在您的回复中设置server_access_token cookie,如提到的@Ben

    response.set_cookie() 会在响应中设置server_access_token cookie,然后客户端可以读取 cookie 并将其发送到请求标头中的进一步请求中。

    class MySocialApplicationRedirectView(View):
    
            def get(self, request, *args, **kwargs):  
                # Here, write your code to fetch the  {application}'s access token, 
                # creating a new user with your server's access token, and then
                # associating it with {application}'s access token
    
                # assign the response to a variable and set the access token as a cookie in the response object
                response = HttpResponseRedirect('/accounts/profile/')       
                response.set_cookie(key, value='my_server_access_token', ..other parameters )
                return response 
    

    注意:为了安全起见,所有请求(获取和使用令牌)都必须使用 HTTPS 端点。

    【讨论】:

    • 感谢您的回答,您的意思是我需要直接更改Python Social Auth的代码吗?
    • 这复制了其他更符合标准的功能。会话 cookie 正是为此目的而创建的,而且客户端代码可能已经支持它们,无需任何特殊处理,因为会话本身由后端管理。
    • @ybbaigo 当你在做问题的第 4、5、6 点时,你必须这样做。在重定向到localhost/accounts/profile 时,您可以设置标头。MySocialApplicationRedirectView 是社交应用程序将重定向到您的服务器正在侦听的 url 的视图。
    • @BenBurns 同意并更新了答案。目的是在客户端将使用令牌的响应标头中发送令牌。响应标头不会在后续请求中传递。因此,令牌将被发送一次并被使用。我避免在 cookie 中设置令牌,因为令牌将在请求标头和请求 cookie 中发送。
    • 不用担心 - 删除了我的反对票。此外,您可能需要注意,非标准标头通常以 X 为前缀,并且通常在标头键中使用连字符而不是下划线,因此为了符合典型约定,您可能希望设置 X-Auth-Token 如果您正在使用标题。事实上,如果你 google 一下,你会发现这个 header key 被许多框架使用,这些框架执行基于 header 的身份验证。
    【解决方案3】:

    它没有回答您的具体问题,但我已经使用TastyPie 解决了类似的问题。它非常简单,虽然不必处理多个应用程序,但由于它为任何给定应用程序提供了一个 API,所以应该不是问题。

    【讨论】:

      猜你喜欢
      • 2017-10-18
      • 2015-03-13
      • 2013-12-03
      • 2019-06-16
      • 1970-01-01
      • 2021-01-05
      • 2017-04-01
      • 2020-01-31
      • 1970-01-01
      相关资源
      最近更新 更多