SpringBoot+Vue使用JWT做登录验证,请给我写个详细完整的例子,包括前端和后端,包括一些配置和工具类,简单一点,不需要Security
时间: 2024-03-23 19:39:44 浏览: 25
好的,下面是一个简单的Spring Boot + Vue + JWT的登录验证示例。
1. 后端实现
1.1 引入依赖
在pom.xml中添加以下依赖:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
```
1.2 编写控制器
创建一个简单的控制器,提供登录和获取用户信息的接口。
```java
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtils jwtUtils;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
} catch (BadCredentialsException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername());
String jwt = jwtUtils.generateToken(userDetails);
return ResponseEntity.ok(new JwtResponse(jwt));
}
@GetMapping("/user")
public ResponseEntity<?> getUser(@AuthenticationPrincipal UserDetails userDetails) {
return ResponseEntity.ok(userDetails);
}
}
```
1.3 编写JWT工具类
创建一个JwtUtils类,用于生成和解析JWT。
```java
@Component
public class JwtUtils {
private static final String SECRET_KEY = "secret";
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return Jwts.builder()
.setClaims(claims)
.setSubject(userDetails.getUsername())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 86400000L))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public String getUsernameFromToken(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateToken(String token, UserDetails userDetails) {
String username = getUsernameFromToken(token);
return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
}
private boolean isTokenExpired(String token) {
Date expiration = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getExpiration();
return expiration.before(new Date());
}
}
```
2. 前端实现
2.1 安装依赖
在项目根目录下运行以下命令安装需要的依赖:
```bash
npm install axios vue-axios jwt-decode --save
```
2.2 创建登录页面
在Vue项目中创建一个登录页面,用于输入用户名和密码,并向后端发送登录请求。
```vue
<template>
<div>
<input type="text" v-model="username" placeholder="Username">
<input type="password" v-model="password" placeholder="Password">
<button @click="login">Login</button>
</div>
</template>
<script>
import axios from 'axios';
import jwt_decode from 'jwt-decode';
export default {
name: 'Login',
data() {
return {
username: '',
password: ''
}
},
methods: {
login() {
axios.post('/api/auth/login', {
username: this.username,
password: this.password
}).then(response => {
const token = response.data.token;
const user = jwt_decode(token);
localStorage.setItem('token', token);
localStorage.setItem('user', JSON.stringify(user));
this.$router.push('/');
}).catch(error => {
console.log(error);
});
}
}
}
</script>
```
2.3 创建路由守卫
创建一个路由守卫,用于检查用户是否已登录。
```js
import axios from 'axios';
import jwt_decode from 'jwt-decode';
const authGuard = (to, from, next) => {
const token = localStorage.getItem('token');
if (!token) {
next('/login');
return;
}
const user = JSON.parse(localStorage.getItem('user'));
const decoded = jwt_decode(token);
if (decoded.sub !== user.username || decoded.exp < Date.now() / 1000) {
next('/login');
return;
}
axios.get('/api/auth/user').then(response => {
const data = response.data;
if (data.username !== user.username) {
next('/login');
return;
}
next();
}).catch(error => {
console.log(error);
next('/login');
});
};
export default authGuard;
```
2.4 创建需要登录才能访问的页面
创建需要登录才能访问的页面,并在路由中添加路由守卫。
```vue
<template>
<div>
<h1>Hello, {{ user.username }}!</h1>
<p>Your roles are:</p>
<ul>
<li v-for="role in user.roles">{{ role }}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Home',
computed: {
user() {
return JSON.parse(localStorage.getItem('user'));
}
}
}
</script>
<style scoped>
h1 {
font-size: 3em;
margin-bottom: 0.5em;
}
ul {
list-style: none;
padding-left: 0;
}
li {
margin-bottom: 0.5em;
}
</style>
```
```js
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
import Login from './views/Login.vue';
import authGuard from './auth-guard';
Vue.use(Router);
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home,
beforeEnter: authGuard
},
{
path: '/login',
name: 'login',
component: Login
}
]
});
```
至此,一个简单的Spring Boot + Vue + JWT的登录验证示例已经完成。当用户输入正确的用户名和密码后,后端会返回一个JWT Token,前端将该Token保存在localStorage中,后续的请求都需要在请求头中带上该Token,后端会根据Token验证用户是否已登录。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)