1.前端布局
<template>
<div id="box">
<!--这里必须使用一个双标签-->
<div id="login_box">
<el-card class="box-card">
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="用户名" prop="name">
<el-input type="text" v-model="ruleForm.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary"
size="mini"
:plain="true"
@click="login"
style="margin-left: 100px;width: 100px">登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</div>
</template>
<script>
export default {
name: "Login",
data(){
return {
ruleForm: {
name: '',
password: ''
},
rules: {
name: [
{required: true, message:'用户名不能为空', trigger: 'blur'},
],
password: [
{required: true, message: '密码不能为空', trigger: 'blur'},
]
}
}
},
methods:{
login(){
//表单校验
this.$refs['ruleForm'].validate((valid) => {
if (valid){
//url:后端登录接口的路径
this.$http.post("http://localhost:8808/system/login",this.ruleForm).then(result=>{
if (result.data.code==2000){
//获取token
var token=result.data.data;
//保存token sessionStorage理解session
sessionStorage.setItem("token",token)
//console.log(token)
//路由跳转
this.$router.push("/home")
}
});
}
})
}
}
}
</script>
<style>
#login_box{
position: relative;
width: 500px;
margin: 250px auto;
}
#login_box div.img_position{
position: absolute;
left: 200px;
top: -70px;
}
.text {
font-size: 14px;
}
.item {
padding: 18px 0;
}
.box-card {
padding: 100px 50px 0 0;
width: 480px;
}
</style>
登录按钮事件
如果想在vue工程中使用axios进行异步请求,则需要在main.js中导入axios
[1]//导入axios
import axios from "axios";
[2]//把axios挂载到vue对象中,以后在vue中如果使用axios直接可以用$http名称
Vue.prototype.$http=axios
methods:{
login(){
//表单校验
this.$refs['ruleForm'].validate((valid) => {
if (valid){
//url:后端登录接口的路径
this.$http.post("http://localhost:8808/system/login",this.ruleForm).then(result=>{
if (result.data.code==2000){
//获取token
var token=result.data.data;
//保存token sessionStorage理解session
sessionStorage.setItem("token",token)
//console.log(token)
//路由跳转
this.$router.push("/home")
}
});
}
})
}
}
2.完成后端登陆接口
(1)创建springboot工程引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lpt</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-vue</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 日期序列化-->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.9.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
(2)mp代码生成器
package com.lpt;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Collections;
/**
* TODO
*
* @author DELL
* @version 1.0
* @since 2022-07-25 19:07:17
*/
public class Generator {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/shiro_permission?serverTimezone=Asia/Shanghai", "root", "xin5211314a")
.globalConfig(builder -> {
builder.author("刘鹏涛") // 设置作者
.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir(".\\src\\main\\java\\"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.lpt") // 设置父包名
.moduleName("system") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, "src\\main\\resources\\mapper\\")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("acl_role_permission")// 设置需要生成的表名
.addTablePrefix("acl_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
(3)配置application
server.port=8808
spring.datasource.druid.url=jdbc:mysql://localhost:3306/shiro-permission?serverTimezone=Asia/Shanghai
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.username=root
spring.datasource.druid.password=root
#日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
(4)接口
@RestController
@RequestMapping("/system")
public class LoginController {
@Autowired
private IUserService userService;
@PostMapping("login")
public CommonResult login(@RequestBody LoginVo loginVo){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username",loginVo.getName());
wrapper.eq("password",loginVo.getPassword());
wrapper.eq("isdeleted",0);
User one = userService.getOne(wrapper);
if(one!=null){
return new CommonResult(2000,"登录成功",null);
}else{
return new CommonResult(5000,"登录失败",null);
}
}
}
前端调用后端登录接口时出现如下的错误
为跨域问题:
当使用异步请求从一个网址访问另一个网址时可能会出现跨域问题。
前提:
1. 必须为异步请求
2. 当端口号或协议或ip不同时则会出现跨域
出现两个请求: 有一个请求的方式为: OPTIONS 和真实的请求方式
理解: OPTIONS先头部队。---探视后台有没有解决跨域。
如何解决跨域:
1.前端解决----但是我不会。
2.后端解决---->这里也有几种方式:
【1】可以借助nginx.
【2】在代码中解决
(origins = {"192.168.0.111:8080","192.168.0.120:8081"},allowedHeaders="运行哪些请求头跨域",methods={"GET","POST"})
origins: 允许哪些域可以跨域访问我这个接口
allowedHeaders:允许哪些请求头信息跨域
methods: 允许哪些请求方式跨域
上面再控制层接口处加上注解的方式解决跨,麻烦的地方就需要对每个控制类都加该注解。 设置一个全局跨域配置类。
@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);
}
}
登录成功后前端路由跳转
3.登录的bug
上面咱们写的登录,后端没有保存数据 前端也没有拿到数据进行保存
修改登录的接口
@RestController
@RequestMapping("/system")
@Api(tags = "登录的接口类")
public class LoginController {
@Autowired
private IUserService userService;
@Autowired
private RedisTemplate redisTemplate;
@PostMapping("login")
@ApiOperation(value="登录接口")
public CommonResult login(@RequestBody LoginVo loginVo){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username",loginVo.getName());
wrapper.eq("password",loginVo.getPassword());
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);
}
}
}
修改前端登录方法
后面每次请求都可以携带该token,
每次请求都得要人为添加参数token. 我们可以使用axios得请求拦截器