钉钉文档介绍了2种二维码登录方式:
钉钉文档-扫码登录第三方网站
- 使用钉钉提供的扫码登录页面
- 将钉钉登录二维码内嵌到自己页面中
这次只实验了第一种方式:
1. 配置回调地址
钉钉开发者-钉钉登录与分享中配置回调地址,通过该地址获取接口回发的信息
2. 配置首页
def index(request):
if request.user.is_authenticated:
return HttpResponse('登陆成功')
else: #未登录则转至二维码登陆页面
return redirect('/orders/dingding_login/')
3. 配置二维码登录页面(钉钉提供):
dingding_login(view)
def ding_url(request):
appid ='ding**********tlevq'#钉钉应用的AppKey
redirect_url='http://127.0.0.1:8000/orders/' #扫码登录成功后的回调地址
return redirect(
'https://oapi.dingtalk.com/connect/qrconnect?appid=' + appid + '&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=' + redirect_url)
4. 回调地址的信息获取及登陆
登陆成功后,API接口通过回调地址的参数发回临时授权码:
code=request.GET.get("code")
采用钉钉文档中根据sns临时授权码获取用户信息的方法:
名称 | 示例值 | 说明 |
---|---|---|
POST地址 | https://oapi.dingtalk.com/sns/getuserinfo_bycode | |
参数accessKey | 应用的AppKey | |
参数timestamp | 1546084445901 | 当前时间戳,单位毫秒 |
参数 signature | ddsdssfsdfxxxx | 签名计算方法文档说明 |
dingding_back (view)
from urllib.parse import quote
from hashlib import sha256
import datetime,time,hmac,base64,requests,json
def ding_back(request):
code=request.GET.get("code") #从回调地址参数中获取临时授权码
data={"tmp_auth_code":code} #定义字典,POST时只接受JSON数据格式
uri='https://oapi.dingtalk.com/sns/getuserinfo_bycode?accessKey='
accessKey='ding************evq' #参数1
timestamp=str(round(time.time()*1000)) #参数2
appSecret='******_Ta_B2B*****M-fIFRz******9ZrY-*********ek2S*********' #计算签名信息使用的密钥
signature=base64.b64encode(hmac.new(appSecret.encode('utf-8'),timestamp.encode('utf-8'), digestmod=sha256).digest()) #签名算法为HmacSHA256
res=requests.post(uri+accessKey+"×tamp="+timestamp+"&signature="+quote(signature),data=json.dumps(data)) #签名信息需要urlEncode
#获取数据
user_dict=json.loads(res.text)
username=user_dict['user_info']['nick'] #获取用户昵称
user=authenticate(request,remote_user=username) #使用remote_user创建本地user实例。
if user is not None:
login(request,username)#使用remote_user登陆
print(user.backend)
return redirect('/首页')
5. url.py配置
path('',views.index,name='index'),#应用首页
path('dingding_login/',views.ding_url,name='ding_login'),#配置登陆url
path('dingding_back/',views.ding_back,name='ding_back'),#回调url
6.setting.py配置
MIDDLEWARE = [
'django.contrib.auth.middleware.PersistentRemoteUserMiddleware',#需要加入这个,用于维持登陆状态
]
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.RemoteUserBackend',#加入这个用于远程用户的创建和验证
'django.contrib.auth.backends.ModelBackend'
]