SpringBoot+Vue前后端分离实战(用户注册登录)
Posted HUTEROX
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot+Vue前后端分离实战(用户注册登录)相关的知识,希望对你有一定的参考价值。
前言
昨天抽空终于把后端架起来了,准备开始编写后端,结果由于是第一次做前后端分离,搞的我闹了不少洋相,查了半天资料发现是个小细节没搞好,气死我。
注册
既然要登录那必然是先少不了注册,注册之后才能去登录呀。
那么咱们这个毕竟是作为一个前后端分离的项目,所以的话注册部分的逻辑也是分两个部分,一个是前端部分,一个是后端部分。
前端部分逻辑
前端其实就两个。
关于这部分的话是前端自己生成了验证码,前端校验账号密码长度是否合法。
关于这部分前端代码见:Vue实战开发(一)验证码与登录页面
发送请求
这个也是比较重要的一部分,我这边使用的是 Axios 发送请求。但是这里一定要注意一个细节
Axios发送的请求参数是封装在requestbody里面的,这个关系到我们后面怎么拿数据,先前我就是不知道这个,搞得我一直接收不到参数
不过在此之前我们必须做一件事前,那就是跨域处理 这一块我是在前端做的,后端没去做,为了保证我后端的安全。
proxyTable:
'/boot':
target: 'http://localhost:8000/',
changeOrigin: true,
pathRewrite:
'^/boot': ''
,
target 是你的服务器,/boot 是指代那个主机。
那么现在我们开始发送请求
Register()
this.axios(
url: "/boot/regist",
method: 'post',
data:
username: this.formRegist.username,
password: this.formRegist.password.toLowerCase(),
).then(res =>
this.flag = res.data.flag;
if(this.flag =='1')
alert("注册成功")
this.$router.push("/login")
else
alert("注册失败用户名已存在!")
)
后端处理
这里的话我要说一下那个参数,那个flag就是来说明用户是否注册成功的,如果成功 flag 为1 反之为 0
现在把目光移步到 springboot
这边的逻辑其实很简单,就是检查用户名是否存在,存在就不注册,然后返回flag
@Controller
public class UserRegist
@Autowired
UserService userService;
@Autowired
RegistMessage registMessage;
@ResponseBody
@PostMapping("/regist")
public RegistMessage SaveUser(@RequestBody Map<String, Object> usermap)
String username = (String) usermap.get("username");
String password = (String) usermap.get("password");
QueryWrapper<User> UsersWrapper = new QueryWrapper<>();
UsersWrapper.eq("UserName",username);
if(userService.IsExitsUser(UsersWrapper))
registMessage.setFlag(0);
return registMessage;
else
User user = new User();
user.setUserName(username);
user.setUserPassword(password);
userService.SaveUser(user);
registMessage.setFlag(1);
return registMessage;
之后在数据库就能见到注册好的账号密码了。
再然后就是前端重新拿到数据
判断情况。
登录
同样的登录也要进行区分,但是这里面稍微麻烦的是这边我们还要生成一个token用来记录用户的登录状态,并且由于是前后端分离,所以我们不能直接用session 或者 cookie ,像先前用Django那样直接request.session,或者 springboot 那样直接 Httpsession 。这边我们需要自己去加密token,并且让前端保存token。
这边我们还是先看到前端吧。
前端唯一要做的就是发送用户和密码,然后接收token。以后请求敏感页面的时候就会带入token。
前端获取token
核心的话就只有这个
logincount()
this.axios(
url: "/boot/login",
method: 'post',
headers: "Huterox": "hello" ,
data:
username: this.formLogin.username,
password: this.formLogin.password.toLowerCase(),
).then(res =>
this.formLogin.success = res.data.success
this.formLogin.token = res.data.token
if(this.formLogin.success =='1')
//设置token七天过期
localStorage.setExpire("token",this.formLogin.token,1000*60*60*24*7);
alert("登录成功~")
this.$router.push("/space")
else
alert("用户名或密码错误!")
)
,
那个success和flag是一个东西。
前端token状态管理
由于没有cookie所以我们这边需要自己保存一下token,但是由于vuex 的session在页面关闭或者刷新之后就没了所以只能用 localStorage 但是这玩意的话没有办法设置过期时间所以还要自己动手处理一下。
封装 localStorage的方法。
Storage.prototype.setExpire=(key, value, expire) =>
let obj=
data:value,
time:Date.now(),
expire:expire
;
localStorage.setItem(key,JSON.stringify(obj));
Storage.prototype.getExpire= key =>
let val =localStorage.getItem(key);
if(!val)
return val;
val =JSON.parse(val);
if(Date.now()-val.time>val.expire)
localStorage.removeItem(key);
return null;
return val.data;
之后敏感页面自己在判断有木有token就好了。
localStorage.getExpire("token")
后端处理
这一套在前端处理起来是相对容易,那么接下来就是后端了。当然在后端主要是涉及到生成token和校验token。毕竟前端只需要判断有误token即可,后端是要验证的,至于怕不怕有人恶意篡改,只要你改了,我后端验证就过不了,我后面引入Redis就专门记录这种情况,正常情况下token不会被恶意篡改,也就是能够通过校验,一旦过不了那很大概率是被恶意篡改了,那就拉入监控名单,次数超过限制关进小黑屋,或者前端调用浏览器定位。安全这块我本人是比较注重的,比较玩过一段时间的信安。
先回到这里,我们继续说说下面怎么处理。
用户登录
之后前端查看返回结果。成功了就有token
生成token
这里用到 jwt
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.6.0</version>
</dependency>
package com.huterox.whiteholeboot.utils.TokenProccessor;
/**
* 生成token
*/
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.huterox.whiteholeboot.Dao.Mapper.UserMapper.UserServer.UserService;
import com.huterox.whiteholeboot.Dao.Pojo.UserPojo.User;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Autowired;
public class TokenProccessor
private static UserService userService=new UserService();
private static final long EXPIRE_TIME=60*60*1000*24*7; //过期时间7天
private static final String KEY = "huterox"; //加密秘钥
/**
* 生成token
* 由于只有当账号密码正确之后才会生成token所以这边只需要用户名进行识别
* @param userName 用户名
* @return
*/
public static String createToken(String userName)
Map<String,Object> header = new HashMap();
header.put("typ","JWT");
header.put("alg","HS256");
JwtBuilder builder = Jwts.builder().setHeader(header)
.setExpiration(new Date(System.currentTimeMillis()+EXPIRE_TIME))
.setSubject(userName)//设置信息,也就是用户名
.setIssuedAt(new Date())
.signWith(SignatureAlgorithm.HS256,KEY);//加密方式
return builder.compact();
/**
* 验证token是否有效
* @param token 请求头中携带的token
* @return token验证结果 2-token过期;1-token认证通过;0-token认证失败
*/
public static int verify(String token)
Claims claims = null;
try
//token过期后,会抛出ExpiredJwtException 异常,通过这个来判定token过期,
claims = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody();
catch (ExpiredJwtException e)
return 2;
//从token中获取用户名,当用户查询通过后即可
String username = claims.getSubject();
User user = userService.selectUserByName(username);
if(user != null)
return 1;
else
return 0;
拦截器设置
这里的话是需要用到拦截器了,主要是后面的处理,登录之后某些请求时需要token的,那么这里就要检验。
package com.huterox.whiteholeboot.Config;
import com.alibaba.fastjson.JSON;
import com.huterox.whiteholeboot.utils.TokePassJson.TokenPassJson;
import com.huterox.whiteholeboot.utils.TokenProccessor.TokenProccessor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class TokenInterceptor implements HandlerInterceptor
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception
if(request.getMethod().equals("OPTIONS"))
response.setStatus(HttpServletResponse.SC_OK);
return true;
response.setCharacterEncoding("utf-8");
String token = request.getHeader("token");
int result = 0;
if(token != null)
result = TokenProccessor.verify(token);
if(result == 1)
System.out.println("通过拦截器");
return true;
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
try
TokenPassJson json = new TokenPassJson();
json.setSuccess(result);//0表示验证失败,2表示过期
response.getWriter().append(JSON.toJSONString(json));
System.out.println("认证失败,未通过拦截器");
catch (Exception e)
e.printStackTrace();
response.sendError(500);
return false;
return false;
package com.huterox.whiteholeboot.Config;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
@Configuration
public class TokenConfig implements WebMvcConfigurer
// @Override
// public void addCorsMappings(CorsRegistry registry)
// registry.addMapping("/**")
// .allowCredentials(true)
// .allowedHeaders("*")
// .allowedMethods("*")
// .allowedOrigins("*");
//
//
// 跨域,我们前端做了跨域所以的话后端不用,也是为了安全,不能什么阿猫阿狗都过来访问
@Override
public void addInterceptors(InterceptorRegistry registry)
List<String> excludePath = new ArrayList<>();
//排除拦截,除了注册登录(此时还没token),其他都拦截
excludePath.add("/regist"); //登录
excludePath.add("/login"); //注册
excludePath.add("/static/**"); //静态资源
excludePath.add("/assets/**"); //静态资源
registry.addInterceptor(new TokenInterceptor())
.addPathPatterns("/**")
.excludePathPatterns(excludePath);
WebMvcConfigurer.super.addInterceptors(registry);
之后就可happy访问了。
总结
进度有点慢,没办法先磨合一些。此为如果觉得本文不错请给个赞赞~(白嫖可耻,尤其是收藏了还不敢赞赞(下次 收藏数>点赞 ?收费:免费))
以上是关于SpringBoot+Vue前后端分离实战(用户注册登录)的主要内容,如果未能解决你的问题,请参考以下文章
基于SpringBoot+SpringCloud+Vue前后端分离项目实战 --开篇
Spring Boot + Vue3 前后端分离实战wiki知识库系统
Vue+SpringBoot 前后端分离实战(mybatisplus多表分页查询+博客显示)
前后端分离 -- SpringBoot + Vue实战项目 部署至阿里云服务器