ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Django OAuth Toolkit

2022-05-20 13:34:35  阅读:199  来源: 互联网

标签:落地 Toolkit 用户 token Client client OAuth Django id


概述

B依托Django OAuth Toolkit, 具备作为OAuth2.0服务器能力, 第三方网站/系统/服务/APP, 可以利用该能力, 获取用户登录信息, 各类资源.

步骤

目的

假设你拥有一个系统A, 希望在系统A的导航条中增加一个按钮, “使用B登录”, 点击后, 用户可以利用B帐号登录系统A, 并获取用户信息和B可向系统A暴露的其他信息.

具体来说, 用户会访问系统A(a), 点击”使用B登录”, 并被跳转到B登录页(b), 如果用户没有登录B, 需要输入用户名密码, 否则用户被询问是否允许使用B帐号登录系统A(c), 用户点击允许, 并跳转回系统A(d), 系统A获得Token, 可以访问用户信息等B接口(e).

了解一些背景知识

OAuth2.0是一种非常通用的工业级授权方式(OAuth 2.0 is the industry-standard protocol for authorization.) 如果你从未听过, 可以参考下列资料做一个粗略了解:

在B注册系统A

注册并登录B.

打开OAuth应用注册页面 你的服务地址/oauth2/applications/, 点New Application

其中Name填自己的应用名称, Client id和Client secret可以用自动生成的.

  • name:应用名称

  • Client id、Client secret自动生成

  • Client type :公开还是机密

  • Authorization grant type 一共有四种

    • 授权码(authorization-code):指的是第三方应用先申请一个授权码,然后再用该码获取令牌,这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。一般针对于用户。此种方式见后面详细介绍。

      ![img](新建 DOCX 文档 - 副本.assets/bg2019040905.jpg)

    • 隐藏式(implicit):有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端

    • 密码式(password):如果你高度信任某个应用,也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌

    • 客户端凭证(client credentials):最后一种方式是凭证式(client credentials),适用于没有前端的命令行应用,即在命令行下请求令牌。这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

      可直接通过client_id和secret直接获取token

      # body
      {
      	"client_id": "xxx",
      	"client_secret": "xxx",
      	"redirect_uri": "http://django-oauth-toolkit.herokuapp.com/consumer/exchange/",
      	"grant_type": "client_credentials"
      }
      
  • Redirect uris:访问以后跳转的地址。

授权码(authorization-code)方式

所谓落地页, 就是访问授权后用户回到的页面.

如果你还没开始开发, 可以先用这个网站试一试, 本页面会生成一个链接,点击后会跳转到授权页面。

在例子中, 落地页应该填: http://django-oauth-toolkit.herokuapp.com/consumer/exchange/

最后点保存, 就完成了B侧的应用注册.

显然, 你需要记下来自己的Client id和Client secret.

用户将看到一个这样的页面(可以通过django国际化进行汉化):

用户点击授权之后, 将会被重定向到你的落地页, 并在url中携带code

在例子中, 应该在该页面, 输入你的Client id和授权url: 你的域名/oauth2/authorize
, 然后获得重定向地址, 并跳转到如下页面

你的落地页后端拿到code之后, 需要请求token, 也就是你的落地页后端需要发一个POST请求:

fetch(new Request('你的域名/oauth2/token/',{
    method:'POST', 
    headers: {'Cache-Control': 'no-cache',
            'Content-Type':'application/x-www-form-urlencoded'},
    body:{
        'client_id':'3RGYcLX5nj9vMT0UbjxjXmYikNrOwEEH2uofF6gq',
'client_secret':'Wu0tcWSpPk3AqUVw1FFS7zWuibEOxELlCp8AtQDPfq2qo991eH8oIGluFSDStEO80ndzWV32e5szIpyNWM5auj8HFTFrzqqnmYo5pYzuI6fFcKdfj90blHgMYivAgWLp',
        'code':'yiKoD7Ms1EvE2dgj5dP51MepkJPFty',
        'redirect_uri':'http://django-oauth-toolkit.herokuapp.com/consumer/exchange/',
        'grant_type':'authorization_code'
    }
})).then((resp)=>{console.log(resp)})

这一步的目的是将明文传输的CODE换成服务器之间传递的TOKEN, 你可以开发另一个落地页2, 或者通过参数复用同一个落地页, 为防混乱, 在本文档中, 我们使用落地页2描述上述POST请求中的${YOUR_CALLBACK_PAGE}

在例子中, 你需要60秒内手动发送上述POST请求, 但是在正式集成中, 应该由落地页的后端自动发送, 按F12打开浏览器调试工具, 填上一个图片中右边的表单, token url是你的域名/oauth2/token/ 点Submit, 就能看到你发出了上述POST请求.

上述POST将给你如下返回值:

{
	"access_token": "aVvBRVFMWPYhZPczNlaWdPTyT5g8Fk",
	"expires_in": 36000,
	"token_type": "Bearer",
	"scope": "read write"
}

凭上述access_token, 用户可以访问B中该用户全部授权资源, 例如, 落地页2应该访问下面API, 获取并展示用户信息, 完成系统A的登录:

获取用户信息接口

url: /api/v2/user/
method: GET
header:

{"Authorization": "Bearer QUgU1t5MvaRuuMtaGy8gTCm3dtdGGL"}

Response

{
		"email": "dfsdfzza@phytium.com.cn",
		"password": "123",
		"last_login": null,
		"username": "fgfdsaasd",
		"last_name": "发给对方",
		"date_joined": "2020-07-23T02:12:34.588741"
	}

后端代码

这样就能返回用户自己的信息了。

class UsersSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = '__all__'
        depth = 1


class UserDetail(generics.GenericAPIView):
    authentication_classes = [OAuth2Authentication]

    def get(self, req, *args, **kwargs):
        user = req.user.users
        serializer = UsersSerializer(instance=user)
        data = serializer.data
        data['user'].pop('password')
        return Response(serializer.data)

标签:落地,Toolkit,用户,token,Client,client,OAuth,Django,id
来源: https://www.cnblogs.com/liuweida/p/16291976.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有