微博三方登录–回调接口
- oauth/model中添加
class OauthUser(models.Model):
OAUTHTYPE = (
('1', 'weibo'),
('2', 'weixin'),
)
uid = models.CharField('三方用户id', max_length=64)
user = models.ForeignKey('userapp.User', on_delete=models.CASCADE)
oauth_type = models.CharField('认证类型', max_length=10, choices=OAUTHTYPE)
- oauth中views.py添加
from django.shortcuts import render
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView
from urllib.parse import urlencode
from userapp.utils import jwt_response_payload_handler
import requests
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
from .models import OauthUser
from userapp.models import User
# 生成前端跳转到微博扫码页面的url
class WeiboUrl(APIView):
'''
生成微博的登陆页面路由地址
https://api.weibo.com/oauth2/authorize? # 微博oauth认证地址
client_id=4152203033& # 注册开发者id
response_type=code&
redirect_uri=http://127.0.0.1:8080/weibo_callback/ # 获取code后将code回调给后端地址
'''
# 自定义权限类
permission_classes = (AllowAny,)
def post(self, request):
url = 'https://api.weibo.com/oauth2/authorize?'
data = {
'client_id': '3516473472', # WEIBO_APP_KEY,
'response_type': 'code',
'redirect_uri': 'http://127.0.0.1:8888/oauth/callback/', # VUE的回调
}
weibo_url = url + urlencode(data)
# https://api.weibo.com/oauth2/authorize?client_id=4152203033&response_type=code&redirect_uri=http://127.0.0.1:8000/api/weibo_back/
# return Response({'weibo_url': weibo_url})
return Response({'code': '0', 'msg': '成功', 'data': {'url': weibo_url}})
# 通过vue前端传入的code,微博身份验证
class OauthWeiboCallback(APIView):
# 自定义权限类
permission_classes = (AllowAny,)
def post(self, request):
# 接收code ,
code = request.data.get('code')
data = {
'client_id': '3516473472',
'client_secret': '7862ee35a0dc6f0345d0464dc34f14fc',
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': 'http://127.0.0.1:8888/oauth/callback/',
}
url = 'https://api.weibo.com/oauth2/access_token'
data = requests.post(url=url, data=data).json() # 拿取请求的返回结果
access_token = data.get('uid')
weibo_uid = data.get('access_token')
# 3. 根据uid 查询绑定情况
try:
oauth_user = OauthUser.objects.get(uid=weibo_uid, oauth_type='1')
except Exception as e:
oauth_user = None
# 返回动作, 登录成功/需要绑定用户 type 0 登录成功, 1, 授权成功, 需要绑定
if oauth_user:
# 4. 如果绑定了, 返回token, 登录成功
user = oauth_user.user
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
# jwt_response_payload_handler为user模块定义的jwt返回的信息
data = jwt_response_payload_handler(token, user)
data['type'] = '0' # 指定为登录成功
return Response({'code': 0, 'msg': '登录成功', 'data': data})
else:
# 5. 如果没绑定, 返回标志, 让前端挑战到绑定页面
return Response({'code': 0, 'msg': '授权成功', 'data': {'type': '1', 'uid': weibo_uid}})
class OauthWeiboBindUser(APIView):
permission_classes = (AllowAny,)
def post(self, request):
# 绑定用户, 1. 已注册用户, 2. 未注册用户
# 1.1 获取用户名, 密码, weibo_uid
username = request.data.get('username')
password = request.data.get('password')
weibo_uid = request.data.get('weibo_uid')
if not all([username, password, weibo_uid]):
return Response({'code': 999, 'msg': '参数不全'})
# 0.判断是否存在此用户
try:
user = User.objects.get(username=username)
except Exception as e:
user = None
# 1. 已注册用户
if user:
# 1.2 , 如果存在就验证 密码, 验证通过,就绑定, 返回token,登录成功
if user.check_password(password):
ou = OauthUser(uid=weibo_uid, user=user, oauth_type='1')
ou.save()
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
data = jwt_response_payload_handler(token, user)
data['type'] = '0' # 指定为登录成功
return Response({'code': 0, 'msg': '登录成功', 'data': data})
else:
return Response({'code': 999, 'msg': '密码错误','data':{}})
else:
# 2. 未注册用户
# 2.1 生成新用户, 设置用户名密码, 保存, 然后绑定, 返回token, 登录成功
user = User(username=username)
user.set_password(password)
user.save()
ou = OauthUser(uid=weibo_uid, user=user, oauth_type='1')
ou.save()
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
data = jwt_response_payload_handler(token, user)
data['type'] = '0' # 指定为登录成功
return Response({'code': 0, 'msg': '登录成功', 'data': data})
'''获取上传token'''
class QNYTokenView(APIView):
def get(self,request):
from qiniu import Auth, put_file, etag
import qiniu.config
# 需要填写你的 Access Key 和 Secret Key
access_key = "PwyTqrclbus4ntRct1o8G2V-qkR1rI7hbd_5Gx29"
secret_key = "IuvSm1vJh2YUiYWFwV-kGmHAJF9R9iGuH2Q1ifea"
# 构建鉴权对象
q = Auth(access_key, secret_key)
# 要上传的空间
bucket_name = 'syl-images'
# 生成上传 Token,可以指定过期时间等
token = q.upload_token(bucket_name, expires=3600)
return Response({'code': 0, 'msg': '获取', 'data': {'uptoken': token}})
3.oauth urls.py
from django.urls import path
from . import views
urlpatterns = [
path('qntoken/', views.QNYTokenView.as_view()), # /oauth/qntoken/
path('weibo/', views.WeiboUrl.as_view()), # /oauth/weibo/ 返回微博登录地址
path('weibo/callback/', views.OauthWeiboCallback.as_view()), # /oauth/weibo/callback/
path('weibo/binduser/', views.OauthWeiboBindUser.as_view()), # /oauth/weibo/callback/
]
微博回调空页面为
http://127.0.0.1:8888/oauth/callback/
微博中回调地址:
http://127.0.0.1:8888/microblog_callback
http://127.0.0.1:8888/microblog_error