# 一、用户名密码登录
前端发送用户名 + 密码 给后端,后端生成并返回可信的 token + 用户信息 供前端使用
id | username | password | name等其他字段
----+----------+----------+----------------
A1 | bob | a1b23f2c | ...
A2 | adam | c0932f32 | ...
# 升级
加上一个数字计算的 图形验证码
验证码
图形验证码的应用范围更加广泛,
# 二 Oathor2.0 授权登录
移动互联网大爆炸时代,密码已经显得不是那么重要了,反正我从来记不住密码,如果手机号码能操作的 app,绝对不用密码来操作。
# 1、参考
- 设计一个可扩展的用户登录系统 (1) - 廖雪峰 (opens new window)
- 设计一个可扩展的用户登录系统 (2) - 廖雪峰 (opens new window)
- 设计一个可扩展的用户登录系统 (3) - 廖雪峰 (opens new window)
# 1、表设计
核心
我们读取到的总是用户的个人资料(Profile),而登录过程只是为了认证用户(Authenticate)
我们可以将个人资料(Profile)和认证用户(Authenticate)信息分离出来 (opens new window)。如果用户登录成功了,我们就可以通过user_id
来匹配 users 表的 id
进而读取 Users 表是来获得用户的 Profile
- users 表
id | name | birth等其他字段
----+------+-----------------
A1 | Bob | ...
A2 | Adam | ...
- local_auth 表(登录方式 1)
id | user_id | username | password
----+---------+----------+-----------
01 | A1 | bob | a1b23f2c
02 | A2 | adam | c0932f32
- third_auth 表(登录方式 2)
id | user_id | oauth_name | oauth_id | oauth_access_token | oauth_expires
----+---------+------------+----------+--------------------+---------------
11 | A1 | wechat | W-012345 | xxxxxxxxxx | 604800
12 | A2 | wechat | W-234567 | xxxxxxxxxx | 604800
13 | A1 | qq | Q-090807 | xxx-xxx-xxx | 86400
14 | A2 | qq | Q-807060 | xxx-xxx-xxx | 86400
# 3、准备
得先去第三方开发平台进行应用登记,开发测试环境登记示例:
- 应用名:lencamo-oauth2
- 应用地址:http://localhost:8080
- 应用回调地址:http://localhost:8080/oauth/callback
然后就可以获得:客户端 ID(client ID)和客户端密钥(client secret)
# 3、github 授权
# 4、QQ 授权
- 简单描述 QQ 第三方登录 (opens new window)
- 具体实现 QQ 第三方登录 (opens new window)
- JS SDK 文档 (opens new window)
- API 列表 (opens new window):只有一个接口用于获取用户基本信息
# 前端
- 引入 QQ 互联的 js JDK,并携带 appid、redirecturi
<script
src="http://connect.qq.com/qc_jssdk.js"
data-appid="100556005"
data-redirecturi="http://www.corho.com:8080/#/login/callback"
></script>
- QQ 登录按钮
<!-- 官方默认的QQ登录按钮 -->
<span id="qqLoginBtn"></span>
<script type="text/javascript">
QC.Login({
btnId: 'qqLoginBtn' //插入按钮的节点id
})
</script>
<!-- 效果:弹出授权小窗口 -->
官方按钮解析
<span id="qqLoginBtn">
<a
href="javascript:;"
onclick="return window.open('https://graph.qq.com/oauth2.0/authorize?client_id=101415280&response_type=token&scope=all&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Fqq-login.html', 'oauth2Login_10458' ,'height=525,width=585, toolbar=no, menubar=no, scrollbars=no, status=no, location=yes, resizable=yes');"
><img
src="https://qzonestyle.gtimg.cn/qzone/vas/opensns/res/img/Connect_logo_7.png"
alt="QQ登录"
border="0" /></a
></span>
<!-- 自定义按钮 -->
<!-- 方式1:无弹窗 -->
<a
href="https://graph.qq.com/oauth2.0/authorize?client_id=100556005&response_type=token&scope=all&redirect_uri=http%3A%2F%2Fwww.corho.com%3A8080%2F%23%2Flogin%2Fcallback"
>
<img src="自定义图片.svg" alt="" />
</a>
<!-- 方式2:有弹窗 -->
<a href="javascript:;" class="icon-login icon-login__qq" data-thirdparty="qq"></a>
- 逻辑判断
accessToken:当前的用户的口令,在口令的过期时间内,可以直接通过 accessToken 来和 QQ 的服务器进行交互,比如说获取用户的昵称,头像的等信息
// callback.vue
if (QC.Login.check()) {
QC.Login.getMe((openId, accessToken) => {
// console.log('openId:', openId)
// console.log('accessToken', accessToken)
// login_type 表示是qq、wechat……
// 调用后台接口(正式登录;用户标识openId)
userQQLogin(openId, accessToken, login_type)
.then((data) => {
// 1、使用qq登录成功
// —— 存储用户信息
const { id, account, avatar, mobile, nickname, token } = data.result
store.commit('user/setUser', { id, account, avatar, mobile, nickname, token })
// —— 跳转到来源页或者首页
router.push(store.state.user.redirectUrl) // '/'
// —— 成功提示
Message({ type: 'success', text: 'QQ登录成功' })
})
.catch((e) => {
// 2、使用qq登录失败(没绑定小兔鲜帐号 、没有小兔鲜帐号)
// —— 显示下一步绑定()、注册页面
isBind.value = false
})
})
}
// callback-bind.vue
if (QC.Login.check()) {
QC.api('get_user_info').success((res) => {
avatar.value = res.data.figureurl_qq_1
nickname.value = res.data.nickname
})
}
# 后端
- 三方登录接口 A(post 请求:/login/social)
前端传入 openId, accessToken, login_type,后端通过这些信息存入数据库,并且还要验证它们的合法性
openId 相当于 username,accessToken 相当于 password,
- 三方登录_账号绑定接口 B(post 请求:/login/social/bind)
前端传入 openId、phone/email、code 验证码,后端通过 user_id 将 third_auth 表的 openId 和 user 表的 phone/email
# 5、微信授权
账号注册:
前端:
- 引入 微信开发平台的 js JDK
<script src="https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
- 微信登录按钮
<div id="wxCode"></div>
<script type="text/javascript">
var obj = new WxLogin({
self_redirect: true,
id: 'login_container',
appid: '应用id',
scope: '',
redirect_uri: '回调地址',
state: '',
style: '',
href: ''
})
</script>
<!-- 效果:弹出授权小窗口 -->
开发应用:vue
<template>
<el-button @click="wxLogin"></el-button>
</template>
<script>
import { onBeforeRouteUpdate } from 'vue-router'
onBeforeRouteUpdate((to) => {
//vue3路由守卫 监听路由地址的变化
console.log('url地址栏变化了', to.fullPath)
//to.fullPath会返回地址url 然后做截取就好了 将code保存调用后端接口即可
//你们可以自己封装一个截取字符串方法 这里我就不封装了
})
const wxLogin = () => {
//点击微信登录图标或者按钮的方法
let redirect_uri = encodeURIComponent('http://www.xxx.com/login') //这里是用户扫码授权后跳转的地址
let appid = 'wx4564811685452155' //这里是网站的appid 需要跟跳转的地址域名绑定过的
let url = `https://open.weixin.qq.com/connect/qrconnect?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect`
window.location.href = url //url就是微信的第三方页面了
}
</script>
# 三、动态验证码登录
移动互联网大爆炸时代,密码已经显得不是那么重要了,反正我从来记不住密码,如果能手机号/邮箱
操作的 app,绝对不用密码来操作。
# 1、简介
目前企业如果要在自己的产品中实现手机验证码或者是邮箱验证码功能,通常需要挑选一家靠谱的短信或邮件发送服务商,并接入其提供的统一接口来实现,在现在也是一种非常主流的实现方式。
# 2、表设计
# 3、实现
接口:
获取-短信验证码接口 A(get 请求:/login/code)
短信验证码-登录接口 B(post 请求:/login/code)。
前端:
用户引入登录页面时,调用 接口 A
若超过验证码超时,前端还得再次调用接口 A
用户点击登录时,前端将 手机号/邮箱 + 验证码 通过接口 B 发生给后端
后端:
若前端传来的 验证码没有过期 且 验证码短信/邮件服务商一致,则向接口 B 返回 token + 用户信息
# 四、滑块验证码
在业务应用中添加滑块验证码一般采取的有两种方式,一种是自主开发,滑块验证码的开发难度并不大;另一种是购买第三方服务商提供的滑块验证码产品。
# 1、简介
常见的图像验证码有:
- 拖动滑块验证 (opens new window)
- 推理拼图、文字点选、图标点选等(b 站、谷歌)
使用图像验证码的场景通常在:
- 注册和登录(防止恶意机器人自动化注册和登录账号)
- 敏感操作(修改密码、进行支付)
- 异常行为检测(防止自动化脚本或爬虫对系统进行滥用或攻击)
- ……
# 2、自主研发(简易版)
# 五、APP 扫码登录
← 身份认证 OAuth2.0授权 →