springboot security+vue 前后端分离 登录接口
时间: 2023-11-26 07:04:19 浏览: 170
前后端分离:springboot+vue
下面是一个简单的 Spring Boot Security + Vue 的前后端分离登录接口示例:
1. 后端实现
首先,我们需要创建一个 Spring Boot 项目,并添加以下依赖:
```xml
<dependencies>
<!-- Spring Boot Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- JSON Web Token -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
```
接下来,我们需要创建一个 User 实体类和 UserRepository 接口,用于管理用户信息。这里我们使用 MySQL 数据库作为数据存储。
```java
@Entity
@Table(name = "users")
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singleton(new SimpleGrantedAuthority("ROLE_USER"));
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
```
然后,我们需要创建一个 Security 配置类,用于配置 Spring Security。
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserRepository userRepository;
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(username -> userRepository.findByUsername(username))
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtTokenProvider));
}
}
```
这个配置类中,我们使用了 BCryptPasswordEncoder 作为密码加密方式,并且使用了自定义的 UserDetailsService 来获取用户信息。此外,我们还配置了一些请求的权限,其中 /api/auth/** 接口是登录接口,我们允许所有人访问。
最后,我们需要创建一个 JwtTokenProvider 类,用于生成和验证 JSON Web Token。
```java
@Component
public class JwtTokenProvider {
private static final String SECRET_KEY = "my-secret-key";
private static final long EXPIRATION_TIME = 86400000L; // 1 day
public String generateToken(User user) {
Date now = new Date();
Date expiration = new Date(now.getTime() + EXPIRATION_TIME);
return Jwts.builder()
.setSubject(user.getUsername())
.setIssuedAt(now)
.setExpiration(expiration)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public Authentication getAuthentication(String token) {
UserDetails userDetails = new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
return user;
}
}.loadUserByUsername(getUsername(token));
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
return false;
}
}
public String getUsername(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
}
}
```
在这个类中,我们定义了一个 SECRET_KEY 和 EXPIRATION_TIME 常量,分别用于生成 JSON Web Token 和设置 Token 的有效期。generateToken() 方法用于生成 Token,getAuthentication() 方法用于根据 Token 获取用户认证信息,validateToken() 方法用于验证 Token 的有效性,getUsername() 方法用于获取 Token 中的用户名。
最后,我们需要创建一个 JwtConfigurer 类,用于配置 Spring Security 的过滤器链。
```java
public class JwtConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
private JwtTokenProvider jwtTokenProvider;
public JwtConfigurer(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Override
public void configure(HttpSecurity http) throws Exception {
JwtTokenFilter customFilter = new JwtTokenFilter(jwtTokenProvider);
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
}
}
```
这个类中,我们创建了一个 JwtTokenFilter 过滤器,并将其添加到 Spring Security 的过滤器链中。
2. 前端实现
在前端,我们使用 Vue 框架来实现登录页面。首先,我们需要安装 axios 库,用于发送 HTTP 请求。
```bash
npm install --save axios
```
然后,我们创建一个 Login.vue 组件,在其中添加一个表单,用于输入用户名和密码。
```html
<template>
<div class="login">
<h1>Login</h1>
<form>
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" id="username" v-model="username">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" v-model="password">
</div>
<button type="submit" class="btn btn-primary" @click.prevent="login">Submit</button>
</form>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'Login',
data() {
return {
username: '',
password: ''
};
},
methods: {
login() {
axios.post('/api/auth/login', {
username: this.username,
password: this.password
}).then(response => {
localStorage.setItem('access_token', response.data.token);
this.$router.push('/');
}).catch(error => {
console.error(error);
});
}
}
};
</script>
```
在这个组件中,我们使用了 axios 库来发送 POST 请求到 /api/auth/login 接口,并在登录成功后将 Token 存储到 localStorage 中,然后跳转到首页。
3. 完整示例
完整的代码示例可以在以下链接中找到:
https://github.com/zhangxu-s/springboot-vue-login-example
阅读全文