环境:springboot2.7 vue2 elementui
效果展示:在cookie中存入了多个用户信息,下拉框显示多个用户名,支持输入
cookie存储信息,前后端分离应注意跨域问题,未采用前后端分离,在无需考虑,此处未使用加密
使用cookie存储用户信息很常见,但是网上的帖子存多个用户的很少,存储单个用户信息的方法当登录新用户时,不改变cookie的名字的情况下,会将旧用户的信息覆盖掉,但是不可能一个用户一个cookie名字,所以将多个用户的信息组成json存入一个cookie
使用cookie存储多个用户信息,思路是在cookie中存入含有用户信息的json,格式如下{"admin":"123456","admin0":"123456"},在后端进行处理,处理思路是
1.找name=userInfo 的cookie,没有,自己新建一个json,将用户信息放入
2.有name=userInfo的cookie,得到一个字符串,解析成json,根据用户名看json中是否有这个用户的信息,有,删了重新加入,没有直接加入
3.加cookie到response中,其实本质还是覆盖了旧同名cookie,但是新cookie的内容是正确的
4返回前端的cookie,在这个位置看到才算存入cookie成功
然后是前端,先拿到userInfo的cookie,这个样子,这个json数据也要保存,之后可以根据用户名作为key,取value
将上述的cookie在放入一个用户对象数组,方便输入框取到这里的数据,用户对象数组如下
输入框获取数据的实现:一个下拉列表(用户名),一个输入框(密码)
用户名:从用户对象数组遍历拿到所有的用户名,
密码:当用户名放生改变时,密码重新赋值为json数据[用户名]
usercontroller
package com.example.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.dao.UserDao;
import com.example.entity.constants.Constants;
import com.example.entity.pojo.User;
import com.example.service.IUserService;
import com.example.utils.Result;
import com.example.utils.TokenUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.List;
import static com.example.utils.CookieOperation.addCookie;
import static com.example.utils.CookieOperation.getCookieValue;
@ApiOperation("用户登录")
@GetMapping("/login")
public Object login(@RequestParam String username, @RequestParam String password, HttpServletResponse response, HttpServletRequest request) throws UnsupportedEncodingException {
User user = userService.getOne(new QueryWrapper<User>().eq("username", username).eq("password", password));
if (null == user) {
return Result.error();
} else {
JSONObject userInfo=new JSONObject();
String str=getCookieValue(request,"userInfo");
if (str!=null){//判断是否存在userInfo的cookie,存在解析处理,不存在,自己新建存入
userInfo = JSON.parseObject(str); //得到一个userInfo的json
//如果userInfo不含有username,则将这个登录信息存入userInfo,若包含userInfo,先移除,在存入,考虑到密码更新问题
if (!userInfo.containsKey(username)){
userInfo.put(username,password);
}
if (userInfo.containsKey(username)&&userInfo.getString(username)!=password){
userInfo.remove(username,userInfo.getString(username));
userInfo.put(username,password);
}
}
if (str==null){
userInfo.put(username,password);
}
addCookie(response,"userInfo",JSON.toJSONString(userInfo), Constants.WEEK,"/");//WEEK是一个常量
String token = TokenUtils.sign(user);//token与处内容无关
return Result.ok().data("user", user).data("token", token);///Result返回结果类
}
}
cookie的工具类,方便操作cookie
package com.example.utils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
public class CookieOperation {
/**
* 添加cookie,同样的key会进行覆盖
*
* @param response
* @param key
* @param value
* @param age
*/
public static void addCookie(HttpServletResponse response, String key, String value, int age) {
Cookie myCookie = new Cookie(key, value);
myCookie.setMaxAge(age);
response.addCookie(myCookie);
}
/**
* 有路径的添加cookie,同样的key会进行覆盖
*
* @param response
* @param key
* @param value
* @param age
* @param path
*/
public static void addCookie(HttpServletResponse response, String key, String value, int age, String path) throws UnsupportedEncodingException {
System.out.println(value);
Cookie myCookie = new Cookie(key, URLEncoder.encode(value, "utf-8"));
myCookie.setMaxAge(age);
myCookie.setPath(path);
response.addCookie(myCookie);
}
/**
* 删除cookie
*
* @param request
* @param response
* @param key
*/
public static void removeCookie(HttpServletRequest request, HttpServletResponse response, String key) {
Cookie myCookie = getCookie(request, key);
if (myCookie != null) {
myCookie.setMaxAge(0);
response.addCookie(myCookie);
}
}
/**
* 得到cookie的value
*
* @param request
* @param key
* @return
*/
public static String getCookieValue(HttpServletRequest request, String key) throws UnsupportedEncodingException {
Cookie myCookie = getCookie(request, key);
if (myCookie == null) return null;
else return URLDecoder.decode(myCookie.getValue(),"utf-8");
}
/**
* 得到cookie
*
* @param request
* @param key
* @return
*/
public static Cookie getCookie(HttpServletRequest request, String key) {
Cookie[] cs = request.getCookies();
for (Cookie i : cs) {
if (i.getName().equals(key)) {
return i;
}
}
return null;
}
/**
* cookie是否存在
*
* @param request
* @param key
* @return
*/
public static boolean isCookieExist(HttpServletRequest request, String key) {
Cookie[] cs = request.getCookies();
for (Cookie i : cs) {
if (i.getName().equals(key)) {
return true;
}
}
return false;
}
}
WebMvcConfig类 ,用于cors跨域配置
package com.example.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.example.interceptor.TokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2020/10/22 0022.
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer pathMatchConfigurer) {
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer contentNegotiationConfigurer) {
}
@Override
public void configureAsyncSupport(AsyncSupportConfigurer asyncSupportConfigurer) {
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer defaultServletHandlerConfigurer) {
}
@Override
public void addFormatters(FormatterRegistry formatterRegistry) {
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
//是否发送Cookie
.allowCredentials(true)
//放行哪些原始域
.allowedOrigins("http://localhost:8081/")
.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
.allowedHeaders("*")
.exposedHeaders("*");
}
@Override
public void addViewControllers(ViewControllerRegistry viewControllerRegistry) {
}
@Override
public void configureViewResolvers(ViewResolverRegistry viewResolverRegistry) {
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> list) {
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> list) {
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> list) {
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> list) {
}
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {
}
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {
}
@Override
public Validator getValidator() {
return null;
}
@Override
public MessageCodesResolver getMessageCodesResolver() {
return null;
}
}
登录表单
<!-- 登录表单区域-->
<el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" class="login_form" label-width="0px">
<el-form-item prop="username">
<el-select v-model="loginForm.username" :placeholder="'请输入您的用户名'" allow-create
filterable style="width: 410px" @change="usernameChange">
<template slot="prefix">
<span style="padding: 5px;line-height: 33px;font-size: 18px; ">
<i class="iconfont icon-user"></i>
</span>
</template>
<el-option
v-for="item in userInfo"
:key="item.username"
:label="item.username"
:value="item.username">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="loginForm.password" prefix-icon="iconfont icon-3702mima"
type="" placeholder="请输入您的密码"></el-input>
</el-form-item>
<!-- 按钮区域-->
<el-form-item class="btns">
<el-button type="primary" @click="login">登录</el-button>
<el-button type="info" @click="">注册</el-button>
</el-form-item>
</el-form>
<script>
export default {
name: "Login",
computed: {
index() {
return index
}
},
data() {
return {
//表单数据
loginForm: {
username: null,
password: null
},
userInfo: {},//用户对象数组,用户对象的属性为用户名,密码
userInfoJson: null,//json格式的用户名和密码
}
},
created() {
this.getUserInfo()
},
methods: {
getUserInfo() {
const userInfo = this.$cookies.get('userInfo')
this.userInfoJson = userInfo
var list = []//数组
for (var userInfoKey in userInfo) {
var user = {}//对象
user.username = userInfoKey
user.password = userInfo[userInfoKey]
console.log(user)
list.push(user)
}
this.userInfo = list
console.log(this.userInfo)
},
usernameChange() {
this.loginForm.password = this.userInfoJson[this.loginForm.username]//当用户名发生改变时,从json中去用户名所对应的密码
},
login() {
this.$refs.loginFormRef.validate(async (valid) => {
if (!valid) return;
const res = await get('/user/login', this.loginForm)
// if (res.code != 200) return this.$message.error('登陆失败')
console.log(res)
this.$message.success('登陆成功')
this.$store.commit('set_Authorization', res.data.token);// token
//2.通过编程时导航跳转到后台主页,路由地址时/home
await router.push({path: '/home'})
})
}
}
}
</script>
坑:
跨域问题:cookie本身不允许跨域,所以需要自行设置,文章中的代码已经设置在webmvconfig中
json的处理问题:json的格式为k:v,但是这里用户名和密码都要做v使用,所以需要借助一个对象数组来辅助存储。
编码问题:新建cookie等可能需要进行编码解码问题
Cookie myCookie = new Cookie(key, URLEncoder.encode(value, "utf-8"));
return URLDecoder.decode(myCookie.getValue(),"utf-8");
cookie中存json:不可以有空格,似乎不太建议在cookie中存入json,因为我在其他网站上很少见