以OAuth2.0授权码模式实现第三方授权登录,原理如下图:
1.User Agent为浏览器,CLient为我们想要登录的应用,Auth login为微博登录页面,Auth server为微博服务器。
2.首先用户通过浏览器进入我们想要登录的应用,通过点击第三方登录,进入微博登录授权页面,登录用户微博账号,微博会询问你是否授权给你想要登录的应用,用户点击授权,会马上将用户名和密码发送给微博服务器,微博验证通过后马上返回给应用前端页面一个code授权码,前端页面接收到授权吗,马上将授权码发送给应用后台服务器(即我们的djang后台服务器),随即服务器django拿着授权码向微博服务器发送请求交换令牌,拿到令牌将令牌马上存储。
注意:第三方登录不仅仅是只为了登录应用。
代码层面,首先在django中配置文件中配置微博第三方登录
WEIBO_CLIENT_ID='2694928935' #应用ID
WEIBO_CLIENT_SECRET='73a1db8e062e6328b34cbcb5b9849b33'
WEIBO_REDIRECT_URI='http://127.0.0.1:7000/dadashop/templates/callback.html' #授权后携带授权码重定向到的网页地址
视图函数层面:
def get_weibo_login_url():
# 生成微波授权地址
params = {
'response_type': 'code',#授权码
'client_id': settings.WEIBO_CLIENT_ID,#应用ID
'redirect_uri': settings.WEIBO_REDIRECT_URI#重定向地址
}
weibo_url = 'https://api.weibo.com/oauth2/authorize?'#微博授权地址
return weibo_url + urlencode(params)#微博授权地址
def get_access_token(code):
# 向微博服务器发请求,拿授权码交换令牌
token_url = 'https://api.weibo.com/oauth2/access_token'
post_data = {
'client_id': settings.WEIBO_CLIENT_ID,
'client_secret': settings.WEIBO_CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': settings.WEIBO_REDIRECT_URI
}
try:
res = requests.post(token_url, data=post_data)#服务器向微博服务器发起请求,请求结果返回在res中
except Exception as e:
print('---post weibo is error')
print(e)
raise
if res.status_code == 200:
return json.loads(res.text)#授权令牌在res.text中
return None
class OAuthUrlView(View):
def get(self, request):
url = get_weibo_login_url()
return JsonResponse({
'code': 200, 'oauth_url': url})
class OAuthView(View):
def get(self, request):
# 接受前段转发的授权码,去微博服务器交换access——token
code = request.GET.get('code')
try:
user_info = get_access_token(code)
print(user_info)
except Exception as e:
result = {
'code': 101006, 'error': 'weibo is busy'}
return JsonResponse(result)
wuid = user_info.get('uid')
access_token = user_info.get('access_token')
# 先检查当前微博用户是否第一次光临
try:
weibo_user = WeiboUser.objects.get(wuid=wuid)
except Exception as e:
print('--weibouser get error---')
WeiboUser.objects.create(access_token=access_token, wuid=wuid)
data = {
'code': 201, 'uid': wuid}
return JsonResponse(data)
else:
# 该用户之前执行过微博授权
# 检查当前用户是否绑定过
uid = weibo_user.uid
if uid:
# 之前绑定过-执行过绑定注册
username = uid.username
token = make_token(username)
result = {
'code': 200, 'username': username, 'data': {
'token': token.decode()}}
return JsonResponse(result)
else:
# 之前微博授权过,当没执行微博注册
data = {
'code': 201, 'uid': wuid}
return JsonResponse(data)