Shiro Redis 实现登录
作为一名经验丰富的开发者,我很高兴能教您如何使用Apache Shiro和Redis实现用户登录。以下是实现该功能的基本步骤和代码示例。
步骤概览
以下是使用Shiro和Redis实现登录的步骤:
步骤 | 描述 |
---|---|
1 | 添加依赖 |
2 | 配置Shiro |
3 | 创建Realm |
4 | 配置Redis |
5 | 实现登录逻辑 |
详细步骤
1. 添加依赖
首先,您需要在项目的pom.xml
文件中添加以下依赖:
<!-- Apache Shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.7.1</version>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. 配置Shiro
在application.properties
文件中配置Shiro:
shiro.loginUrl = /login
shiro.successUrl = /home
shiro.unauthorizedUrl = /unauthorized
3. 创建Realm
创建一个继承自AuthorizingRealm
的类,并实现doGetAuthenticationInfo
和doGetAuthorizationInfo
方法:
public class MyRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
User user = userService.findByUsername(usernamePasswordToken.getUsername());
if (user == null) {
return null;
}
return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
User user = (User) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRole(user.getRole());
return info;
}
}
4. 配置Redis
配置Redis缓存,以便在认证成功后缓存用户的会话信息:
@Configuration
public class RedisConfig {
@Bean
public RedisCacheManager cacheManager(LettuceConnectionFactory connectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.build();
}
}
5. 实现登录逻辑
在控制器中实现登录逻辑:
@Controller
public class LoginController {
@Autowired
private SecurityUtils securityUtils;
@GetMapping("/login")
public String login() {
return "login";
}
@PostMapping("/login")
public String doLogin(@RequestParam String username, @RequestParam String password, RedirectAttributes redirectAttributes) {
try {
securityUtils.getSubject().login(new UsernamePasswordToken(username, password));
return "redirect:/home";
} catch (AuthenticationException e) {
redirectAttributes.addFlashAttribute("message", "Invalid username or password");
return "redirect:/login";
}
}
}
类图
以下是Shiro和Redis相关的类图:
classDiagram
class User {
+String username
+String password
+String role
}
class UserService {
+User findByUsername(String username)
}
class MyRealm {
+AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
+AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
}
class LoginController {
+String login()
+String doLogin(String username, String password, RedirectAttributes redirectAttributes)
}
class RedisConfig {
+RedisCacheManager cacheManager(LettuceConnectionFactory connectionFactory)
}
通过以上步骤,您可以实现使用Shiro和Redis的用户登录功能。希望这能帮助您快速上手。祝您学习顺利!