pc端项目登陆
方式一:微信扫码登陆
1、参考网站:
https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
2、前致条件
1、申请(微信开放平台的管理中心):选择对应的端(移动h5,网站pc,小程序,公众号等)填写基础信息(需要公司的信息填写)
要注意回调的域名,授权回调的域名
2、申请成功之后:
AppId
AppSecret
====> 从接口里取
使用参数
参数 | 说明 |
---|---|
appid | 应用唯一标识 |
redirect_uri | 请使用urlEncode对链接进行处理 |
response_type | 填code |
scope | 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login |
state | 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 |
lang | 界面语言,支持cn(中文简体)与en(英文),默认为cn |
3、展示
步骤1:在页面中先引入如下JS文件(支持https):
http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js
步骤2:在需要使用微信登录的地方实例以下JS对象:
var obj = new WxLogin({
self_redirect:true,
id:“login_container”,
appid: “”,
scope: “”,
redirect_uri: “”,
state: “”,
style: “”,
href: “”
});
参数 | 说明 |
---|---|
self_redirec | true:手机点击确认登录后可以在 iframe 内跳转到 redirect_uri,false:手机点击确认登录后可以在 top window 跳转到 redirect_uri。默认为 false。 |
id | 第三方页面显示二维码的容器id |
appid | 应用唯一标识,在微信开放平台提交应用审核通过后获得 |
scope | 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 |
redirect_uri | 重定向地址,需要进行UrlEncode |
state | 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 |
style | 提供"black"、"white"可选,默认为黑色文字描述。详见文档底部FAQ |
href | 自定义样式链接,第三方可根据实际需求覆盖默认样式,stylelite不为1时有效。详见文档底部FAQ。注意: |
stylelite | 切换二维码登录样式,值为1时二维码登录将切换到新样式。详见文档底部FAQ。 |
fast_login | 启用或禁用快速登录功能,值为0时将禁用快速登录。 |
将微信登录二维码内嵌到自己页面vue项目中
1、在body里创建一个script标签
let scDom = document.createElement('script')
2、script标签的src 进行赋值
scDom.src = 'http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'
3、通过appendChild添加到body里面去
document.body.appendChild(scDom)
4、实例化:onloading: 保证这个script是加载完的
scDom.onload = async () =>{
let res = await getLoginParam()
let { appid, scope, redirectUri, state } = res.data
// 这些关键参数我们是从参数里拿的
var obj = new WxLogin({
id:"wxCode",
appid,
scope,
redirect_uri: decodeURIComponent(redirectUri),
state,
href:"data.text/css:base64,jghhjfiajsifdhbjkdhxgsj''
});
}
//href参数如果需要传递Base64编码的字符串,可以var base64Str = btoa("你的字符串"); // 使用btoa进行Base64编码
如果是多端扫码登陆需要定时器300毫秒去调用接口轮循,
4、用户扫码之后的行为
拒绝:啥都不做
允许:正常来说(是有cookie)但是现在做演示,我们的后端就给我们放在了重定向的url里token
1、解析url
2、拿到token: 在hooks里做永久化存储
const displayUrlParams = () => {
const urlParams = new URLSearchParams(window.location.search)
console.log(urlParams)
if(urlParams.size){
// 1、拿到了token
const token = urlParams.get('token')
userInfo(token)
}
}
方式二:手机验证码登陆
手机验证码主要注意短信防止被刷
1、点击发送短信
要先去看有没有输入 =====> 还要去看合法不合法(判断+正则:/^1[3-9]\d{9}$/)
2、展示插件:(网上有,如图片滑块)
1、前端向服务端请求接口(拿滑块图片等内容)
1、前端参数:
验证方式类型type、前端生成uuid、时间戳:
2、后端要干啥?
三个参数: 把三个参数进行一个整合 uuid 加密 生成了一个secretKey
3、后端返回的内容:
1、一个大图:缺口是已经存在的
2、一个小滑块的图
3、又返回给我们加密后的key(基于我们给它的三个参数生成的)
2、展示插件:拿到后端给我们的图渲染到页面上,然后呢,把后端给我们的secretKey(加密过后)保存起来
3、用户的行为
1、鼠标按下
2、鼠标滑动
只有前端css的一些交互,没有什么逻辑行为
3、鼠标松开(我们前端不知道正确位置在哪?所以我们要去把位置给到后端,让后端给我们结果)
3.1 前端给后端传了什么内容?
传的位置: ===》 是拿secretKey(是后端第一次加密之后返回给我们的一个值) + 位置 ======> 进行再次加密的值 ====> 后端
3.2 后端做事?
拿到我们的这个加密之后的值:对应去解密,解密之后就会有一个位置, 解密出来的一个位置 去和数据库的正确位置 进行匹配,
3.2.1 不正确就返回失败, 失败之后 也应该出现一张新的图,再重新走一遍这个流程
3.2.2 正确之后 发送短信
进行了多次加密;安全性就非常高。
五、防刷开发流程
1、引入插件
1.1 定义变量:
从接口中拿的变量
1.2 调接口
****参数名称、接口名称、接口地址
1.3 去拿位置再次请求接口,接口返回给我们是否正确,正确就发短信、不正确的话我们再次去走一遍以上的流程
2、输入手机号、验证码 去调登录接口
成功之后会有token ====> 拿token请求用户信息:hooks去做一个永久化存储,token也需要存储
方式三:账号密码登陆
登录后操作
1、拿到token
2、token存储
存cookie还是存localStorage
3、拿token去换取用户信息
3.1 永久化存储
3.2 hooks
浏览器的四种本地存储方式-cookie,localStorage,sessionStorage,IndexedDB
存储问题:localStorag
1、localStorage
1.1 不管存进去的是什么内容,取出来永远都是一个字符串
一般用JSON.stringify()和JSON.parse
1.2 localStorage
浏览器不同,大小是不同,大概是5M
========>
localStorage超过最大存储量怎么办?
1、压缩存储字节的大小(lz-string)
1.1: 下载
npm install lz-string
1.2 引入
import LZString from 'lz-string'
1.3 使用方法
存:localStorage.setItem('B', LZString.compress(a))
取:LZString.decompress(localStorage.getItem('B'))
优点:节省一定的空间
缺点:需要额外引入一个库
2、indexedDB =====>
2.1 首先这个东西比我们localStorage 大N多倍
2.2 含义:这是一个内置于浏览器中的完整文档数据库
2.3 下载安装(方便我们使用封装好的库)
npm install localforage
// 引入
import localforage from 'localforage';
// 配置
localforage.config({
name: 'my-app', // 数据库名称
storeName: 'my-store', // 存储对象的名称
})
// 存
localforage.setItem('myKey', {a: 123})
.then(() => {
console.log('数据保存成功');
})
.catch((error) => {
console.error('数据保存失败:', error);
});
// 取
localforage.getItem('myKey')
.then((value) => {
console.log('获取到的数据:', value);
})
.catch((error) => {
console.error('获取数据失败:', error);
});
优点:存储量很大
缺点:兼容性不太好,相比之下使用起来有一点繁琐
持久化存储
1、下载安装
cnpm install pinia-plugin-persist
2、main.ts配置
import piniaPluginPersist from 'pinia-plugin-persist'
// 配置
const store = createPinia()
store.use(piniaPluginPersist)
app.use(store)
3、对应模块使用
{
........
persist: {
enabled: true,
strategies: [
{
paths: ['userInfo'], /// 要存什么内容
storage: localStorage // 存在哪里
}
]
}
}
五、hooks
1、是什么?
Hooks本质上就是一组可复用函数
2、为什么要用?
当多个组件都共享这个函数中的逻辑,我们就可以将这些逻辑封装hooks,然后在需要的组件中去使用它。这样做就可以避免代码重复写,提高代码的复用性。
3、怎么用?
export const userInfo(){} //user开头的名称