springboot+vue+elementUI前后端分离项目练习—小试牛刀

确定技术栈

后端技术栈:

  • springboot
  • mybatis plus
  • shiro
  • lombok
  • redis
  • hibernate validatior(springboot内置)
  • jwt

后端开发步骤:

1、建好数据库
2、springboot整合mybatis plus(整合之后别忘了先测试一下)
3、前后端统一结果封装

这里我们用到了一个Result的类,这个用于我们的异步统一返回的结果封装。一般来说,结果里面有几个要素必要的

  • 是否成功,可用code表示(如200表示成功,400表示异常)
  • 结果消息
  • 结果数据
package com.ryan.common.lang;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.io.Serializable;

@Data
public class Result implements Serializable {
   
    //状态码,200一般表示正常,非200表示异常
    private int code;
    //信息
    private String msg;
    //数据
    private Object data;

    //操作成功的结果封装
    //对于前端来说,操作成功一般都是200,他们一般比较注重我data,所以我们需要进一步封装
    public static Result success(Object data){
   
        return success(200,"操作成功",data);
    }

    //方法封装,方便别处调用
    public static Result success(int code,String msg,Object data){
   
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        result.setData(data);
        return result;
    }

    //往往操作失败之后,没有什么数据返回的,看中的是msg,所以我们可以再进一层封装
    public static Result fail(String msg){
   
        return success(400, msg,null);
    }

    //操作失败的状态码一般是400,msg一般是错误原因什么的,所以这里最好也加上
    public static Result fail(String msg, Object data){
   
        return success(400,msg,data);
    }

    //操作失败的结果封装
    public static Result fail(int code,String msg,Object data){
   
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        result.setData(data);
        return result;
    }


}
4、shiro整合jwt逻辑分析
  • 登陆逻辑
    在这里插入图片描述
  • 访问资源(接口)时的shiro&jwt逻辑
    在这里插入图片描述
shiro代码编写

考虑到后面可能需要做集群、负载均衡等,所以就需要会话共享,而shiro的缓存和会话信息,我们一般考虑使用redis来存储这些数据,所以,我们不仅仅需要整合shiro,同时也需要整合redis。在开源的项目中,我们找到了一个starter可以快速整合shiro-redis,配置简单,这里也推荐大家使用。

而因为我们需要做的是前后端分离项目的骨架,所以一般我们会采用token或者jwt作为跨域身份验证解决方案。所以整合shiro的过程中,我们需要引入jwt的身份验证过程。

第一步:导入shiro-redis的starter包:还有jwt的工具包,以及为了简化开发,我引入了hutool工具包。

<dependency>
    <groupId>org.crazycake</groupId>
    <artifactId>shiro-redis-spring-boot-starter</artifactId>
    <version>3.2.1</version>
</dependency>
<!-- hutool工具类-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.3.3</version>
</dependency>
<!-- jwt -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

第二部:配置shiro

package com.ryan.config;

import com.ryan.shiro.AccountRealm;
import com.ryan.shiro.JwtFilter;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * shiro启用注解拦截控制器
 */
@Configuration
public class ShiroConfig {
   
    @Autowired
    JwtFilter jwtFilter;
    @Bean
    public SessionManager sessionManager(RedisSessionDAO redisSessionDAO) {
   
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionDAO(redisSessionDAO);
        return sessionManager;
    }
    @Bean
    public DefaultWebSecurityManager securityManager(AccountRealm accountRealm,
                                                     SessionManager sessionManager,
                                                     RedisCacheManager redisCacheManager) {
   
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(accountRealm);
        securityManager.setSessionManager(sessionManager);
        securityManager.setCacheManager(redisCacheManager);
        /*
         * 关闭shiro自带的session,详情见文档
         */
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);
        return securityManager;
    }
    //shiro过滤器链的定义
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
   
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        Map<String, String> filterMap = new LinkedHashMap<>();
        //所有的链接都会经过我们jwt
        filterMap.put("/**", "jwt"); // 主要通过注解方式校验权限
        chainDefinition.addPathDefinitions(filterMap);
        return chainDefinition;
    }
    @Bean("shiroFilterFactoryBean")
        public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager,
                                                             ShiroFilterChainDefinition shiroFilterChainDefinition) {
   
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        Map<String, Filter> filters = new HashMap<>();
        filters.put("jwt", jwtFilter);
        shiroFilter.setFilters(filters);
        Map<String, String> filterMap = shiroFilterChainDefinition.getFilterChainMap();
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }

    // 开启注解代理(默认好像已经开启,可以不要)
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
   
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
   
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        return creator;
    }
}

第三步:导入jwt工具类

package com.ryan.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * jwt工具类
 */
@Slf4j
@Data
@Component
@ConfigurationProperties(prefix = "ryan.jwt")
public class JwtUtils {
   

    private String secret;
    private long expire;
    private String header;

    /**
     * 生成jwt token
     */
    public String generateToken(long userId) {
   
        Date nowDate = new Date();
        //过期时间
        Date expireDate = new Date(nowDate.
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值