前端特殊点:
在前后端未分离时:
前端页面:
和jsp写法差不多,需要更改几处。
编写登陆页面:
和jsp一样,此处省略
main文件配置
后端
使用代码生成器生成代码
参见
添加一个与前端交互的包vo他和entity包一样,都是实体类,但vo是和前端交互用的,entity是和数据库交互用的
定义一个登录类
@RestController
@RequestMapping(value = "/system")
@Api(tags = "登录接口类")
public class LoginCon {
@Autowired
IUserService userService;
@ApiOperation(value = "登录接口方法")
@PostMapping(value = "/login")
public CommonResult login(@RequestBody LoginVo loginVo){
System.out.println(loginVo);
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username",loginVo.getUid());
wrapper.eq("password",loginVo.getUpwd());
wrapper.eq("is_deleted",0);
User one = userService.getOne(wrapper);
if(one != null){
return new CommonResult(2000,"登录成功",null);
}else {
return new CommonResult(5000,"登陆失败",null);
}
}
}
使用代码生成器生成代码
代码生成器使用参照
修改前端代码;
登陆测试报错:跨域问题
当使用异步请求从一个网址访问另一个网址时可能会出现跨域问题。
前提:
1. 必须为异步请求
2. 当端口号或协议或ip不同时则会出现跨域
解决问题
1.前端解决
2.后端解决---->这里也有几种方式:
【1】可以借助nginx.
【2】在代码中解决
这里介绍后端解决方案
第一种加注解
在控制层需要的接口上添加@CrossOrigin
@CrossOrigin
属性:
origins = {"192.168.0.111:8080","192.168.0.120:8081"},allowedHeaders="运行哪些请求头跨域",methods={"GET","POST"})
origins: 允许哪些域可以跨域访问我这个接口
allowedHeaders:允许哪些请求头信息跨域
methods: 允许哪些请求方式跨域
请求类型
用法
第二种(推荐)
如果使用注解,拿需要在所有接口上都加,工作量很大。
使用全局跨域配置类 的话只需配置一次
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
// 当前跨域请求最大有效时长。这里默认1天
private static final long MAX_AGE = 24 * 60 * 60;
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
corsConfiguration.setMaxAge(MAX_AGE);
source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}
修该登录页面进行路由跳转
上面写的登录,后端没有保存数据 前端也没有拿到数据进行保存.
解决方案
在登录接口,随机生成一个字符串token,而且唯一不重复,把token作为redis的key,把用户信息
作为value,存入到redis中,然后把token放入common Result的data上;
这样前端就拿到了token,
当需要查询权限时,将token传给后端,后端根据token查redis取到用户信息,再查询。
利用redis保存用户数据
添加redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
添加配置
修改登陆接口
@RestController
@RequestMapping(value = "/system")
@Api(tags = "登录接口类")
public class LoginCon {
@Autowired
IUserService userService;
@Autowired
private RedisTemplate redisTemplate;
@ApiOperation(value = "登录接口方法")
@PostMapping(value = "/login")
public CommonResult login(@RequestBody LoginVo loginVo){
System.out.println(loginVo);
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username",loginVo.getUid());
wrapper.eq("password",loginVo.getUpwd());
wrapper.eq("is_deleted",0);
User one = userService.getOne(wrapper);
if(one != null){
//随机生成一个唯一字符串。
String token = UUID.randomUUID().toString();
//把该token作为redis的key value为当前登录用户信息
ValueOperations forValue = redisTemplate.opsForValue();
/*存值,并设置有效时间*/
forValue.set(token,one,24, TimeUnit.HOURS);
return new CommonResult(2000,"登录成功",token);
}else {
return new CommonResult(5000,"登陆失败",null);
}
}
}
修改vue页面
sessionStorage它相当于session
测试
连接redis数据库
查看是否有值
虽然问题解决,但这种方式有多少个接口就需要传token多少次耗费资源
使用axios的请求拦截器
上面的方式不完美,这里使用另一种方式。使用axios的请求拦截器,在请求头上添加token。
添加配置类:
/*设置axios请求拦截器,在请求头上添加token*/
axios.interceptors.request.use(config=>{
/*从session获取token值*/
var token = sessionStorage.getItem("token");
/*token为空是假,不为空为真*/
if(token){
/*在请求头上携带token*/
config.headers.token=token;
}
return config;
});
添加测试页面
结果获取到了: