大家都使用过三方登录 例如(QQ、微信、微博)那我就带着大家学习一下三方登录,并且我们好引入工厂模式来进行,开始吧
工厂模式
首先我们简单介绍一下工厂模式。大家都知道有一造车知名企业,在疫情期间 ,竟然开始生产口罩
是什么原因呢!就是工厂模式所带来的好处 ,就是你给我什么 ,我就给你生产什么。
工厂收到钢铁,那就开始制造汽车 。收到针线 ,就开始制造口罩。
demo事例
class Dingding:
# 钉钉登录类
def __repr__(self):
return "钉钉登录"
def geturl(self):
return '123'
class GitEe:
# 码云登录类
def __repr__(self):
return "码云登录"
def geturl(self):
return '456'
# 工厂类
class SimpleFactory:
@staticmethod # 静态方法无需实例化 直接调用
def product_login(name):
if name == "dingding":
return Dingding()
elif name == "gitee":
return GitEe()
demo1 = SimpleFactory.product_login('dingding')
print(demo1.geturl())
代码实现
1.封装
# 解密
from django.contrib.auth.hashers import check_password, make_password
# 返回HttpResponse
from django.http import HttpResponse
# 解码
from django.utils.baseconv import base64
# 返回Response
import time
import hmac
import base64
from hashlib import sha256
import urllib
import json
import requests
class DingDing:
# 钉钉登录类
def __repr__(self, code):
t = time.time()
# 时间戳
timestamp = str((int(round(t * 1000))))
appSecret = 'YCoNtgYLMDKNS9096KKrnDDazZ7IgJHtGiOA7Y0YvTB8c4tn2vRBvaj_GTIvMkHQ'
# 构造签名
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=dingoa2kslvfvtiaeic7wi",
data=json.dumps(payload), headers=headers)
# 转换为json格式
res_dict = json.loads(res.text)
return res_dict
def geturl(self):
appid = 'dingoa2kslvfvtiaeic7wi' # 应用中的appid
redirect_uri = 'http://127.0.0.1:8000/user/dindin_back/' # 钉钉返回信息的回调地址
return {
"dindin_url": "https://oapi.dingtalk.com/connect/qrconnect?appid=" + appid + '&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=' + redirect_uri}
class GitEe:
def __repr__(self, code):
print(code)
r = requests.post(
"https://gitee.com/oauth/token?grant_type=authorization_code&code=" + code + "&client_id=bef8beab2a56f463fff62bc93bbd87072b5fc1904c6282ca7807d9523038ec52&redirect_uri=http://127.0.0.1:8000/user/gitee_back/&client_secret=b8f5cf324427f286b49276d6db87900b54c8ed49d9d21a88c65ca4e76fa6151c")
access_token = eval(r.text).get("access_token")
# print(access_token)
req = requests.get("https://gitee.com/api/v5/user?access_token=" + str(access_token))
# 转换为json格式
res_dict = json.loads(req.text)
return res_dict
def geturl(self):
return {
"gitee_url": "https://gitee.com/oauth/authorize?client_id=bef8beab2a56f463fff62bc93bbd87072b5fc1904c6282ca7807d9523038ec52&redirect_uri=http://127.0.0.1:8000/user/gitee_back/&response_type=code"}
# 工厂类
class Plant:
@staticmethod
def product_login(name, code):
# 判断是否携带code值 有则回调 没有则返回url
if code:
if name == "dindin_back":
d = DingDing()
return d.__repr__(code)
elif name == "gitee_back":
g = GitEe()
return g.__repr__(code)
else:
if name == "dingding":
d = DingDing
return DingDing()
elif name == "gitee":
return GitEe()
# demo = Plant.product_login('gitee', '123123123')
# print(demo.geturl())
2.djang/app/views.py
# 工厂模式 三方登录
class PlantLoginAPIView(APIView):
permission_classes = (AllowAny,)
# 获取三方登录 url地址
def post(self, request):
why = request.data.get("why")
url = plant_login.Plant.product_login(why, None)
return Response(url.geturl())
# 回调地址 获取用户详细信息
def get(self, request):
code = request.GET.get("code")
# 可以用很多方法实现 查找 包含 都可
# 获取当前url地址 切分后为 ['','user','***_back','']
details = plant_login.Plant.product_login(request.path_info.split('/')[2], code)
return Response({"msg": "ok", "details": details})
3.djang/app/urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('url/', PlantLoginAPIView.as_view()), # gitee__钉钉 三方登录地址
]
vue发送
<template>
<div>
<center><h1>用户登录</h1></center>
<a-form-item label="用户名" v-bind="formlayout">
<a-input ref="userNameInput" v-model="username" placeholder="Basic usage">
<a-icon slot="prefix" type="user"/>
<a-tooltip slot="suffix" title="Extra information">
<a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
</a-tooltip>
</a-input>
</a-form-item>
<a-form-item label="密码" v-bind="formlayout">
<a-input prefix="*" suffix="" v-model="password"/>
</a-form-item>
<a-form-item label="验证码" v-bind="formlayout">
<a-input v-model="verification" @blur="isVerification"/>
<span v-if="isverification">验证码错误</span>
<a-button type="primary" @click="clickVerification">点击发送验证码</a-button>
</a-form-item>
<a-form-item v-bind="buttonlayout">
<a-button type="primary" @click="submit">登录</a-button>
<img style="margin-left:20px;cursor:pointer;" @click="dingding" src="三方登录-工厂模式-钉钉gitee.assets/F05F658D6F.png"/>
<img style="margin-left:20px;cursor:pointer;" @click="gitee" src="三方登录-工厂模式-钉钉gitee.assets/c9C1ED39B9.png"/>
<h1>Facebook社交登录</h1>
<div class="fb-login-button" data-size="large" data-button-type="continue_with" data-layout="default"
data-auto-logout-link="false"
data-onlogin="login" data-use-continue-as="false" data-width=""></div>
</a-form-item>
</div>
</template>
<script type="text/javascript">
import {postgitee, getisVerification, getVerification, postDinDin, postLogin} from "../http/apis";
export default {
data() {
return {
selected: "",
startdate: "",
uid: "",
username: "",
password: "",
verification: "",
isverification: false,
//表单样式
formlayout: {
//标签
labelCol: {
xs: {span: 24},
sm: {span: 8}
},
//文本框
wrapperCol: {
xs: {span: 24},
sm: {span: 3}
}
},
//按钮样式
buttonlayout: {
//按钮
wrapperCol: {
xs: {
span: 24,
offset: 0
},
sm: {span: 16, offset: 8}
}
}
}
},
//自定义方法
methods: {
facebook() {
// crossorigin="anonymous" src="三方登录-工厂模式-钉钉gitee.assets/9bFE8eBF1Ats=1" nonce="BBgy4tba"
FB.login(function (response) {
console.log(response);
});
},
gitee() {
postgitee({why: "gitee"}).then(res => {
console.log(res)
window.open(res.gitee_url)
})
},
//判断验证码
isVerification() {
getisVerification({verification: this.verification, uid: this.uid}).then(res => {
console.log(res)
if (res.code == 200) {
this.isverification = false
} else {
this.isverification = true
}
}).catch(err => {
console.log(err)
})
},
//发送钉钉验证码
clickVerification() {
getVerification().then(res => {
console.log(res)
this.uid = res.uid
}).catch(err => {
console.log(err)
})
},
//钉钉登录
dingding: function () {
postDinDin({why: "dingding"}).then(res => {
console.log(res)
//打开新窗口跳转到此地址
window.open(res.dindin_url)
})
// window.location.href = "http://localhost:8000/dingding_url/";
},
submit: function () {
// let just = true;
// just = this.isVerification() & just;
if (this.isverification === false) {
let params = {
username: this.username,
password: this.password,
}
//登录
postLogin(params).then(res => {
console.log(res)
if (res.token) {
localStorage.setItem("token", res.token)
localStorage.setItem("username", res.username)
localStorage.setItem("id", res.id)
} else {
alert("登录失败")
}
}).catch(err => {
console.log(err)
})
}
};
</script>
<style type="text/css">
</style>
觉得文章写的不错,可以请喝杯咖啡
- Post link: https://yanxiang.wang/%E4%B8%89%E6%96%B9%E7%99%BB%E5%BD%95-%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F-%E9%92%89%E9%92%89gitee/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.