Spring Boot+JWT+Shiro+MybatisPlus怎么实现Restful快速开发后端脚手架

发布时间:2021-11-15 15:36:31 作者:柒染
来源:亿速云 阅读:158

Spring Boot+JWT+Shiro+MybatisPlus怎么实现Restful快速开发后端脚手架

在现代Web开发中,快速搭建一个高效、安全的后端服务是每个开发者的追求。Spring Boot作为Java生态中最流行的框架之一,以其简洁的配置和强大的功能赢得了广泛的青睐。结合JWT(JSON Web Token)、Shiro(Apache Shiro)和MybatisPlus,我们可以快速构建一个功能完善的后端脚手架。本文将详细介绍如何使用这些技术栈实现一个Restful风格的后端服务。

1. 项目初始化

首先,我们需要创建一个Spring Boot项目。可以使用Spring Initializr来快速生成项目骨架。选择以下依赖:

生成项目后,导入到IDE中,确保项目结构如下:

src
├── main
│   ├── java
│   │   └── com
│   │       └── example
│   │           └── demo
│   │               ├── config
│   │               ├── controller
│   │               ├── entity
│   │               ├── mapper
│   │               ├── service
│   │               └── DemoApplication.java
│   └── resources
│       ├── application.yml
│       └── mapper
└── test
    └── java
        └── com
            └── example
                └── demo

2. 配置MybatisPlus

MybatisPlus是Mybatis的增强工具,提供了许多便捷的功能。首先,我们需要在application.yml中配置数据库连接和MybatisPlus的相关设置:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.demo.entity
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

接下来,创建一个实体类User

@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String username;
    private String password;
    private String role;
}

然后,创建Mapper接口UserMapper

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

3. 集成Shiro和JWT

Shiro是一个强大的安全框架,而JWT是一种轻量级的身份验证机制。我们将结合两者来实现用户认证和授权。

首先,添加Shiro和JWT的依赖:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.7.1</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

接下来,创建一个JWT工具类JwtUtil

public class JwtUtil {
    private static final String SECRET_KEY = "your-secret-key";

    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1天
                .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
                .compact();
    }

    public static String getUsernameFromToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }
}

然后,配置Shiro的RealmFilter

public class JwtRealm extends AuthorizingRealm {
    @Autowired
    private UserMapper userMapper;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole(user.getRole());
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String jwtToken = (String) token.getPrincipal();
        String username = JwtUtil.getUsernameFromToken(jwtToken);
        if (username == null) {
            throw new AuthenticationException("Invalid token");
        }
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            throw new AuthenticationException("User not found");
        }
        return new SimpleAuthenticationInfo(username, jwtToken, getName());
    }
}
public class JwtFilter extends AuthenticatingFilter {
    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String token = httpRequest.getHeader("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            return null;
        }
        return new JwtToken(token.substring(7));
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        AuthenticationToken token = createToken(request, response);
        if (token == null) {
            return true;
        }
        try {
            getSubject(request, response).login(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

最后,配置Shiro的SecurityManagerFilter

@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);

        Map<String, Filter> filters = new HashMap<>();
        filters.put("jwt", new JwtFilter());
        factoryBean.setFilters(filters);

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/**", "jwt");
        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return factoryBean;
    }

    @Bean
    public SecurityManager securityManager(JwtRealm jwtRealm) {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        securityManager.setRealm(jwtRealm);
        return securityManager;
    }

    @Bean
    public JwtRealm jwtRealm() {
        return new JwtRealm();
    }
}

4. 实现Restful API

现在,我们可以实现一些Restful API来测试我们的脚手架。首先,创建一个UserController

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserMapper userMapper;

    @PostMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password) {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user != null && user.getPassword().equals(password)) {
            return JwtUtil.generateToken(username);
        }
        throw new RuntimeException("Invalid username or password");
    }

    @GetMapping("/info")
    public User info(@RequestHeader("Authorization") String token) {
        String username = JwtUtil.getUsernameFromToken(token.substring(7));
        return userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
    }
}

5. 测试

启动项目后,可以使用Postman或其他工具测试API。首先,调用/user/login接口获取JWT令牌,然后在请求其他接口时在Header中添加Authorization: Bearer <token>

6. 总结

通过Spring Boot、JWT、Shiro和MybatisPlus的结合,我们快速搭建了一个功能完善的后端脚手架。这个脚手架不仅支持用户认证和授权,还提供了Restful风格的API接口。希望本文能帮助你快速上手这些技术,并在实际项目中应用它们。

推荐阅读:
  1. Spring Boot和Spring Cloud的联系
  2. 构建RESTful服务(使用Spring Data JPA)

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring boot mybatisplus restful

上一篇:CentOS 8中怎么用nftables

下一篇:jquery如何在div内增加元素

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》