OAuth2.0授权认证
oauth2.0是什么?
OAuth(开放授权)是⼀个开放标准,允许⽤户让第三⽅应⽤访问该⽤户在某⼀⽹站上存储的私密的
资源(如照⽚,视频,联系⼈列表),⽽⽆需将⽤户名和密码提供给第三⽅应⽤。
Oauth2.0的四种授权模式?
https://www.cnblogs.com/Innocent-of-Dabber/p/11009811.html
隐式授权模式(Implicit Grant)
授权码授权模式(Authorization code Grant)
密码模式(Resource Owner Password Credentials Grant)
客户端凭证模式(Client Credentials Grant)
Django+vue实现新浪微博登陆
新浪微博开放平台:https://open.weibo.com/
一、准备工作
二、接口调用
- OAuth2.0授权认证
接口 | 说明 |
---|---|
OAuth2/authorize | 请求用户授权Token |
OAuth2/access_token | 获取授权过的Access Token, UID |
三、使用
微博流程图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GqmWMHwS-1606896785490)(C:\Users\feifei\AppData\Roaming\Typora\typora-user-images\1606896077566.png)]
#### oauthapp/views.py
from urllib.parse import urlencode
import requests
from django.contrib.auth.hashers import make_password
from rest_framework.views import APIView
from rest_framework.response import Response
from oauthapp.models import OauthUser
from syl_pro.settings import WEIBO_APP_ID, WEIBO_SECRET_KEY
# Create your views here.
from userapp.models import User
from utils.MyBaseView import create_token
class WeiBoURl(APIView):
"""
获取微博二维码的url
"""
def post(self, request):
url = 'https://api.weibo.com/oauth2/authorize?' # 微博授权的地址
# 携带的参数配置
data = {
'client_id': WEIBO_APP_ID,
'redirect_uri': 'http://127.0.0.1:8888/oauth/callback/',
}
weibo_url = url + urlencode(
data) # https://api.weibo.com/oauth2/authorize?client_id=1584596336&redirect_uri=http%3A%2F%2F127.0.0.1%3A8888%2Foauth%2Fcallback%2F&response_type=code
return Response({'code': '0', 'msg': '成功', 'data': {'url': weibo_url}})
class WeiBoCallback(APIView):
'''
发送微博返回的code,进行身份验证
'''
def post(self, request):
code = request.data.get("code")
data = {
'client_id': WEIBO_APP_ID,
'client_secret': WEIBO_SECRET_KEY,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': 'http://127.0.0.1:8888/oauth/callback/',
}
url = "https://api.weibo.com/oauth2/access_token"
# *******************************************************
# 需要用一个http请求去请求微博准备的信息-----requests
json_weibo_data = requests.post(url=url, data=data).json()
# *******************************************************
# 提取其中有用的信息UID
uid = json_weibo_data.get("uid")
# 判断是否获取到UID
if uid:
try:
uid_user = OauthUser.objects.get(uid=uid)
res_data = {
'code': 0,
"msg": "授权成功",
"data": {
"type": "0",
"uid": uid,
"username": uid_user.user.username,
"token": create_token(uid_user.user)
}
}
return Response(res_data)
except Exception as e:
res_data = {
'code': 0,
"msg": "授权成功",
"data": {
"type": "1",
"uid": uid,
}
}
return Response(res_data)
else:
return Response({"code": 999, "msg": "获取微博信息失败"})
class WeiBoBindUser(APIView):
"""
绑定三方登录用户
"""
def post(self, request):
oauth_type = 1
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": 4005, "msg": "参数不全"})
# 判断username是否存在
try:
user = User.objects.get(username=username)
oauthinfo = OauthUser.objects.create(uid=weibo_uid, oauth_type=oauth_type,
user=user)
data = {
"authenticated": True,
"id": user.id,
"a": None,
"name": user.nick_name,
"username": username,
"email": user.email,
"token": create_token(user),
"type": 0
}
res_data = {
"code": 0,
"msg": "登陆成功",
"data": data
}
return Response(res_data)
except Exception as e:
password = make_password(password)
user = User.objects.create(username=username, password=password)
oauthinfo = OauthUser.objects.create(uid=weibo_uid, oauth_type=oauth_type,
user=user)
data = {
"authenticated": True,
"id": user.id,
"role": None,
"name": user.nick_name,
"username": username,
"email": user.email,
"token": create_token(user),
"type": 0
}
res_data = {
"code": 0,
"msg": "登陆成功",
"data": data
}
return Response(res_data)
###### oauthapp/models.py 创建三方登陆用户关联表
from django.db import models
from userapp.models import User
# Create your models here.
class OauthUser(models.Model):
OAUTHTYPE = (
('1', 'weibo'),
('2', 'weixin'),
)
uid = models.CharField('三方用户id', max_length=64)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
oauth_type = models.CharField('认证类型', max_length=10, choices=OAUTHTYPE)
-----------------------------------------------------------
###### oauthapp/serializers.py
from django.contrib.auth.hashers import make_password
from rest_framework import serializers
from userapp.models import *
from oauthapp.models import OauthUser
class OauthUserSer(serializers.ModelSerializer):
class Meta:
model = OauthUser
fields = "__all__"
depath = 1
多方式登陆
from django.contrib.auth.backends import ModelBackend
class PPAuth(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
user = models.User.objects.get(Q(username=username) |
Q(phone=username) | Q(email=username))
if user is not None and user.check_password(password):
return user