所有第三方登录都要先获取第三方应用的Id和秘钥
开发之前,需要前往第三方登录的开发者平台QQ、新浪微博、Github,注册账号并填写信息申请接入,成功后会给你一个ID和秘钥,以后你就通过该ID和秘钥来获取令牌,从而实现第三方登录。申请ID和秘钥时Github不需要审核,很简单,而QQ和新浪微博需要审核,稍微麻烦一点。
获得ID和秘钥后需要在setting中进行设置
以钉钉登录为例:关键点就是获取到钉钉的凭证appid,然后将appid跟我们的用户模型联系起来。
这是钉钉的开发者文档:我们应先做好准备工作,可以借鉴以下文档,完成前期准备工作http://wiki.connect.qq.com/准备工作_oauth2-0事件订阅 - 钉钉开放平台钉钉会向应用推送订阅的事件,例如部门变更、签到通知、打卡通知等。通过订阅这些事件,可以更好地与钉钉集成。你只需告诉钉钉当某个事件发生时,钉钉需要推送消息到哪个URL,钉钉会以HTTPhttps://open.dingtalk.com/document/org/push-eventshttp://wiki.connect.qq.com/准备工作_oauth2-0 第三方登录都有其相应的开发者文档。
我们先用一张流程图来简单了解一下钉钉第三方登录都需要做什么,为我们写代码,带来一些思路
图画的不是太好,但是基本还是可以帮我们理解一下第三方登录流程,以及梳理第三方登录的思路。
我们先把前端写一下,前端生成二维码
前端
// 钉钉登录
dingding: function () {
var appid = "dingoajf8cqgyemqarekhr";
var redirect_uri = 'http://127.0.0.1:8080/' + "dingding";
var url =
"https://oapi.dingtalk.com/connect/qrconnect?appid=" +
appid +
"&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=" +
redirect_uri;
window.open(url, "_blank");
window.location.href = url;
},
appid需要我们自己去钉钉的开发者文档去注册,获取到appid之后我们就可以生成钉钉第三方登录的二维码了
如上图所示
接下来我们来写一下钉钉扫码之后的逻辑,是否绑定已经注册的用户
跳转中....
绑定用户
用户名:
{{username_message}}
密码:
重点以及难以理解的代码,上边都有注释,在此就不一一解释
后端
首先我们定义一下模型类
class OauthUser(models.Model):
"""
第三方登录表(微信登录/qq登录/微博登录)
"""
__tablename__ = 'oauth_user'
image = models.CharField(max_length=255, verbose_name='头像', unique=True, null=True)
uid = models.CharField(max_length=255, verbose_name='第三方登录的id', unique=True, null=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
oauth_type = models.CharField(max_length=255, verbose_name='第三方登录类型')
class Meta:
db_table = 'oauth_user'
def __str__(self):
return self.uid
定义好模型类之后我们就可以进行下边的逻辑代码的实现
class DingDingCallBack(APIView):
"""
钉钉三方登录回调
"""
def post(self, request):
# 获取code
code = request.data.get('code')
t = time.time()
# 时间戳
timestamp = str((int(round(t * 1000))))
appSecret = 'Fcah25vIw-koApCVN0mGonFwT2nSze14cEe6Fre8i269LqMHRI2Mu9VK'
# 构造签名
signature = base64.b64encode(
hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod=sha256).digest())
# 请求接口,换取钉钉用户名
payload = {'tmp_auth_code': code}
headers = {'Content-Type': 'application/json'}
res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=' + urllib.parse.quote(
signature.decode("utf-8")) + "×tamp=" + timestamp + "&accessKey=dingoajf8cqgyekhr",
data=json.dumps(payload), headers=headers)
res_json = res.json()
if res_json['errcode'] != 0:
return {'message': res_json['errmsg'], 'code': 500, 'data': {'uid': '110'}}
unid = res_json['user_info']['unionid']
# 查找用户是否已经添加绑定关系
user = OauthUser.objects.filter(uid=unid).first()
if user:
# 用户已经添加绑定关系
if user.user:
# 直接返回主页面
return Response({'message': 'ok', 'code': 200, 'data': res})
return Response({'message': 'Not bind account', 'code': 201, 'data': unid})
在这里我们在扫码之后要判断用户是否已经绑定了已经注册的用户,如果没有就然后用户绑定一下,如果已经绑定就直接登录成功
下边就是绑定用户的一些代码
class BindDingDing(APIView):
"""
绑定钉钉账号
"""
def post(self, request):
unid = request.data.get('unid')
username = request.data.get('username')
password = request.data.get('password')
user = User.objects.get(username=username)
rest = check_password(password, user.password)
if not rest:
return Response({'message': '账号密码错误', 'code': 405})
oauth = OauthUser.objects.filter(uid=unid).first()
if oauth:
return Response({'message': '该用户已经绑定,无法重复绑定', 'code': 403})
dingding = '钉钉'
users = User.objects.get(username=username)
dingding = OauthUser.objects.create(user=users, uid=unid, oauth_type=dingding)
dingding.save()
data = [{
'username': username, 'id': unid
}]
return Response({'message': '绑定成功', 'code': 200, 'data': data})
在此代码中,我们也得进行一些必要的判断
以上就是django配合vue以及钉钉实现的第三方登录,希望可以帮到屏幕前的你