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的类,并实现doGetAuthenticationInfodoGetAuthorizationInfo方法:

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的用户登录功能。希望这能帮助您快速上手。祝您学习顺利!