登录业务模式
1.单一服务器模式
早起单一服务器,用户认证。通过对session域的设置
2.SSO,单点登录模式
分布式,SSO模式
优点:
(1)用户身份信息独立管理,更好地分布式管理。
(2)可以自己扩展安全策略
缺点:
认证服务器访问压力较大
3 常用的单点登录模式
(1) session广播域机制实现 session复制 缺点是消耗的资源过大(不推荐使用)
(2)使用cookie+ redis实现
- --在项目中任何一个模块进行登录以后,把数据放到两个地方
redis:在key,生成唯一随机值(ip,用户id等等) ,在value :用户数据
cookie:在redis里面生成key值,放到cookie里面
-----访问项目中其他模块,发送请求你带着cookie进行发送,获取cookie值,拿着cookie做事情
把cookie获取值,到redis里面进行查询,根据key进行查询,如果查询到数据就是登录
(3)使用token(令牌)实现
1.在项目某个模块进行登录,登录之后,按照规则生成字符串,把登陆之后用户包含到生成字符串里面,把字符串返回
-可以把字符串通过cookie返回
-把字符串通过地址栏返回
2.再去访问项目的其他木块,每次访问在地址栏带着生成字符串,在访问模块里面获取地址栏字符串,根据字符串获取用户信息,如果可以获取的到,就是登录
login.js
import request from '@/utils/request'
export default {
//登录
submitLoginUser(userInfo) {
return request({
url: `/educenter/member/login`,
method: 'post',
data: userInfo
})
},
//根据token获取用户信息
getLoginUserInfo() {
return request({
url: `/educenter/member/getMemberInfo`,
method: 'get'
})
}
}
把login.js引入到login.vue
1.开启第一步操作,调用接口登录返回的token字符串
2.把第一部返回token字符串放到cookie里面(记得引入js-cookie)
login.vue
<script>
import '~/assets/css/sign.css'
import '~/assets/css/iconfont.css'
import cookie from '~/node_modules/js-cookie'
import loginApi from '@/api/login'
export default {
layout: 'sign',
data () {
return {
//封装登录手机号和密码对象
user:{
mobile:'',
password:''
},
//用户信息
loginInfo:{}
}
},
methods: {
//登录的方法
//第一步 调用接口登录返回token字符串
submitLogin(){
loginApi.submitLoginUser(this.user)
.then(response =>{
//第二步 字符串放到cookie里面
//第一个参数:cookie名称,第二个参数:参数的值,第三个参数:参数的作用范围
cookie.set('guli_token',response.data.data.token,{domain:'localhost'})
checkPhone (rule, value, callback) {
//debugger
if (!(/[1-9]\d{7,10}@qq\.com$/.test(value))) {
return callback(new Error('邮箱格式不正确'))
}
return callback()
}
}
}
</script>
<style>
.el-form-item__error{
z-index: 9999999;
}
</style>
3.创建前端拦截器
判断cookie里面是否有token字符串,如果有,把token字符安川放到header(jwt请求头)
request.js
import axios from 'axios'
import { MessageBox, Message } from 'element-ui';
import cookie from 'js-cookie';
//创建axios实例
const service = axios.create({
baseURL: 'http://localhost:9001', //api的base_url
timeout: 20000 //请求超时时间
})
//第三步 创建拦截器 http request 拦截器
service.interceptors.request.use(
config => {
//debugger
//判断cookie中是否有名称叫 guli_token的数据
if (cookie.get('guli_token')) {
//把获取到的cookie值放到header中
config.headers['token'] = cookie.get('guli_token');
}
return config
},
err => {
return Promise.reject(err);
})
export default service
4,根据token值,调用接口,根据token获取用户信息,为了首页面显示,把调用接口返回用户信息放到cookie里面
login.vue
methods: {
//登录的方法
//第一步 调用接口登录返回token字符串
submitLogin(){
loginApi.submitLoginUser(this.user)
.then(response =>{
//第二步 字符串放到cookie里面
//第一个参数:cookie名称,第二个参数:参数的值,第三个参数:参数的作用范围
cookie.set('guli_token',response.data.data.token,{domain:'localhost'})
//第四步调用接口,根据token获取用户信息,为了页面显示
loginApi.getLoginUserInfo()
.then( response =>{
//获取返回的用户信息,放到cookie中
this.userInfo = JSON.stringify(response.data.data.userInfo)
cookie.set('guli_ucenter',this.userInfo,{domain:'localhost'})
//跳转页面
window.location.href = "/";
})
})
},
5.在首页面显示用户信息,从cookie获取用户信息,这个用户信息显示要放在公共页面
default.vue
<script>
import "~/assets/css/reset.css";
import "~/assets/css/theme.css";
import "~/assets/css/global.css";
import "~/assets/css/web.css";
import cookie from '~/node_modules/js-cookie'
export default {
data() {
return {
token: "",
loginInfo: {
id: "",
age: "",
avatar: "",
mobile: "",
nickname: "",
sex: "",
},
};
},
created() {//第五步
this.showInfo()
},
methods:{
//创建方法,从cookie获取用户信息
showInfo(){
//从cookie获取用户信息
var userStr = cookie.get("guli_ucenter");
//把字符串转成json对象形式
//console.log(cookie)
if (userStr&&userStr != 'underfined') {
this.loginInfo =JSON.parse(userStr)
}
},
//退出
logout(){
//清空cookie值
cookie.set('guli_token','',{domain:'localhost'})
cookie.set('guli_ucenter','',{domain:'localhost'})
//回到首页面
window.location.href = "/";
}
}
};
</script>
这里整出来好多错误,最难搞的是一个XXXXX token u in JSON at positoin的错误
跟一个大佬咨询后明白,这个登录的流程是用户登录后向后端发送登录请求,后端响应请求给前端的cookie,前端接收到后端传来的cookie解析一下就行了
这是正常流程,不正常的是一致报错XXXXX token u in JSON at positoin
解决思路:
前后端分开找
后端用swagger测登录接口是否能返回tooken,结果是能的,那就说明后端没写错
前端打印cookie,看看有没有,然后再login.vue和default.vue各下一个console.log(cookie)
发现lonig.vue没有打印出来,后来仔细分析后端包的错误
上网查了一下,发现是jwt格式错了
后来仔细分析第四步的路径,发现写的和第一步一样(尴尬。。。。),然后改过来就行了。