将令牌传递给客户端

时间:2015-09-05 13:45:07

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

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

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

社交认证过程应该是:

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

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

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

3 个答案:

答案 0 :(得分:2)

您可能已经为您的用户提供了Django会话所需的内容。也就是说,如果您正在使用会话中间件(没有此类型的auth几乎是不可能的),您的身份提供者特定令牌通常将填充在extra_data模型的SocialUser dict中提供者有问题。

例如,假设您有对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

答案 1 :(得分:1)

您不应在/?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端点。

答案 2 :(得分:0)

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