vue shiro实现登录
Vue 与 Shiro 实现登录功能
Vue 作为前端框架与 Shiro 作为后端安全框架结合实现登录功能,需要前后端分离协作。以下是具体实现方案:
前端 Vue 实现
安装 axios 用于发送 HTTP 请求:
npm install axios
创建登录组件 Login.vue:
<template>
<div>
<input v-model="username" placeholder="用户名"/>
<input v-model="password" type="password" placeholder="密码"/>
<button @click="login">登录</button>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
username: '',
password: ''
};
},
methods: {
login() {
axios.post('/api/login', {
username: this.username,
password: this.password
}).then(response => {
localStorage.setItem('token', response.data.token);
this.$router.push('/dashboard');
}).catch(error => {
console.error('登录失败', error);
});
}
}
};
</script>
后端 Shiro 配置
添加 Shiro 依赖(Maven):
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.8.0</version>
</dependency>
配置 Shiro 的 Realm:
public class CustomRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 授权逻辑
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
String password = new String(upToken.getPassword());
// 验证用户名密码
if ("admin".equals(username) && "123456".equals(password)) {
return new SimpleAuthenticationInfo(username, password, getName());
}
throw new AuthenticationException("用户名或密码错误");
}
}
配置 Shiro 的 Filter 和 SecurityManager:
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/api/login", "anon");
filterChainDefinitionMap.put("/", "authc");
factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return factoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager(CustomRealm realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
}
创建登录接口:
@RestController
@RequestMapping("/api")
public class LoginController {
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(request.getUsername(), request.getPassword());
try {
subject.login(token);
String sessionId = (String) subject.getSession().getId();
return ResponseEntity.ok().body(Collections.singletonMap("token", sessionId));
} catch (AuthenticationException e) {
return ResponseEntity.status(401).body("认证失败");
}
}
}
跨域与 Token 验证
配置跨域支持(Spring Boot):
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*");
}
}
前端请求携带 Token:
axios.interceptors.request.use(config => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
安全注意事项
密码传输应使用 HTTPS 加密 后端应对密码进行加盐哈希处理(如 BCrypt) 前端应实现 Token 过期处理机制 敏感接口应添加 CSRF 防护

这种实现方式结合了 Vue 的前端交互能力和 Shiro 的后端安全控制,实现了完整的认证流程。前后端通过 Token 进行状态保持,Shiro 负责后端的权限控制和会话管理。






