权限相关,个人自己参考

前端

request axios 的拦截器
// 封装axios
import axios from 'axios'

import {Message, MessageBox} from 'element-ui'

// 创建一个axios对象
const instance = axios.create();

instance.defaults.baseURL = 'http://localhost:8080';
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// instance.defaults.withCredentials = true;
// 配置拦截器
instance.interceptors.request.use(function (config) {
      // 在发送请求之前做些什么
      config.headers['token'] = window.sessionStorage.getItem('token')
      return config;
    },
    function (error) {
      // 对请求错误做些什么
      return Promise.reject(error);
    }
);


instance.interceptors.response.use(
    function (res) {
      if (res.data.code == 200) {
        return res;
      }
      // 判断是否有权限
      if (res.data.code == 401) {
        Message({
          message: '没有权限',
          type: 'error'
        })
      } else {
        Message({
          message: res.data.message,
          type: 'error'
        })
      }
    },
    function (error) {
      console.log(arguments)
      MessageBox.alert(error.message, '系统提示', {
        confirmButtonText: '确定',
        type: 'error'
      })
      return Promise.reject(error);
    }
);
export default instance;
Login.vue
<template>

  <div class="center-container">
    <el-card style="width: 500px;">
      <div slot="header">
        登陆
      </div>

      <el-form ref="loginForm" :model="loginForm" :rules="loginFormRules">

        <el-form-item prop="account">
          <el-input v-model="loginForm.account" placeholder="账号/手机/邮箱">
            <template slot="prepend">
              <i class="fa fa-user"></i>
            </template>
          </el-input>
        </el-form-item>

        <el-form-item prop="password">
          <el-input v-model="loginForm.password" placeholder="密码" show-password>
            <template slot="prepend">
              <i class="fa fa-lock"></i>
            </template>
          </el-input>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" style="width: 100%" @click="submitLoginForm">登陆</el-button>

          <!--router-link方式-->
          <router-link to="/index.html">router-link链接方式</router-link><br>

          <a href="index.html">直接使用超链接a标签</a>

        </el-form-item>

      </el-form>

    </el-card>
  </div>

</template>

<script>
  import qs from 'qs'

  export default {
    name: "Login",
    data() {
      return {

        loginForm: {
          account: 'admin',
          password: '123456'
        },
        loginFormRules: {
          account: [
            {required: true, message: '账号必填'}
          ],
          password: [
            {required: true, message: '密码必填'}
          ]
        }

      };
    },
    watch: {
      'loginForm.account'() {
        console.log(this.loginForm)
      }
    },
    methods: {
      submitLoginForm() {
        this.$refs.loginForm.validate((valid) => {
          if (!valid) {
            return false;
          }
          // 发送ajax请求执行登陆
          // 构建一个axios使用get请求的配置对象
          // let config = {
          //   params: this.loginForm
          // };
          this.axios.post('/api/login.json',qs.stringify(this.loginForm)).then(res=>{
            console.log(res)
            let result = res.data;
            if(result.code == 200){
              console.log(result.data);

              window.sessionStorage.setItem('loginUser',JSON.stringify(result.data));
              window.sessionStorage.setItem('token',result.token);
              // 使用提示框完成显示
              // 跳转到首页
              // 使用代码的方式跳转地址
              this.$router.push('/index.html');
              // // query中的对象会直接拼接到url地址后面,类似于get请求
              // this.$router.push({path:'/index.html',query:{id: 12}});
              // // params中对象不会拼接到url地址后面,类似于post请求的参数
              // this.$router.push({path:'/index.html',params:{id: 12}});
              // this.$router.push({name:'test',query:{id: 12}})
              // this.$router.push({name:'test',params:{id: 12}})

            }else{
              // 使用提示框完成显示
              this.$message({
                message: result.message,
                type: 'error'
              });
            }
          })


        });

        console.log(this.loginForm)
      }
    }

  }
</script>

<style >

  .center-container{
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-around;
  }
  .center-container .el-form-item__error{
    padding-left: 55px;
  }

</style>

后端

Authorization
package com.xuetang9.frame.uam.intercepter;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author 洋葱
 * @version 1.0.0
 * @date 2020/6/17 15:10
 * @copyright 老九学堂
 */
@Target(value = {ElementType.METHOD,ElementType.TYPE}) // 注解的位置
@Retention(RetentionPolicy.RUNTIME) // 注解存在的时机
public @interface Authorization {

    /**
     * session范围的key值
     * @return
     */
    String scope() default "SESSION_LOGIN_TICKET";

    /**
     * 是重定向还是转发
     * @return
     */
    boolean forward() default true;
    /**
     * 重定向的地址
     * @return
     */
    String redirect() default "/no_authorization";
}
AuthorizationInterceptor
package com.xuetang9.frame.uam.intercepter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xuetang9.frame.uam.util.JsonResult;
import com.xuetang9.frame.uam.util.Token;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;

/**
 * 身份授权校验
 * @author 洋葱
 * @version 1.0.0
 * @date 2020/6/17 14:43
 * @copyright 老九学堂
 */
public class AuthorizationInterceptor implements HandlerInterceptor {
    /**
     * 请求处理之前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("进入了拦截器");
        System.out.println("当前正在执行的handler");
        System.out.println(handler);
        System.out.println(handler.getClass());
        // 处理方法级的处理器(值当前处理的是Controller中方法)
        if( !(handler instanceof HandlerMethod)){
           return true;
        }
        // 转换类型
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        // 配合注解来使用
        // 获取表示验证的注解
        Authorization authorization = handlerMethod.getMethodAnnotation(Authorization.class);
        // 如果方法上没有注解,就获取类上的注解
        if(authorization == null){
            authorization = handlerMethod.getBeanType().getAnnotation(Authorization.class);
        }
        // 如果注解对象仍然为null,就表示不要验证
        if(authorization == null){
            return true;
        }
        // 进入验证
        // 获取session中保存的信息
        Object ticket = request.getSession().getAttribute(authorization.scope());
        System.out.println("--------------- interceptor ---" + request.getSession().getId());
        if(ticket == null){
            // 从请求头中获取token
            String token = request.getHeader("token");
            System.out.println("token ---------" + token);
            // 校验token
            ObjectMapper objectMapper = new ObjectMapper();
            Token tokenObj = objectMapper.readValue(token, Token.class);
            long interval =tokenObj.getInterval();
            long time = tokenObj.getCurrentTime();
            if(time + interval > System.currentTimeMillis()){
                // 过期
                return true;
            }
            // 转发还是重定向
            if(authorization.forward()){
                request.getRequestDispatcher(authorization.redirect()).forward(request, response);
            }else {
                response.sendRedirect(request.getContextPath() + authorization.redirect());
            }
            return false;
        }
        return true;
    }

    /**
     * 处理请求完成渲染之前
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 请求完成之后
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
AppController
package com.xuetang9.frame.uam.web;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xuetang9.frame.uam.domain.User;
import com.xuetang9.frame.uam.domain.query.LoginQuery;
import com.xuetang9.frame.uam.intercepter.Authorization;
import com.xuetang9.frame.uam.service.UserService;
import com.xuetang9.frame.uam.util.JsonResult;
import com.xuetang9.frame.uam.util.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 洋葱
 * @version 1.0.0
 * @date 2020/6/12 14:26
 * @copyright 老九学堂
 */
@RestController
@RequestMapping("/api")
@CrossOrigin
public class AppController {

    private static final String SESSION_LOGIN_TICKET = "SESSION_LOGIN_TICKET";

    @Autowired
    private UserService userService;

    @PostMapping("/login.json")
    public JsonResult login(LoginQuery query, HttpSession session) throws JsonProcessingException {
        // 创建一个用于响应JSON结果的对象
        JsonResult jsonResult = new JsonResult();

        // 执行登陆业务并得到登陆后的用户信息
        User loginUser = userService.login(query);
        // 判断登陆是否成功
        if(loginUser == null){
            jsonResult.setCode(9999);
            jsonResult.setMessage("账号或者密码错误");
        }else{
            // 保存登陆信息到session中
            session.setAttribute(SESSION_LOGIN_TICKET, loginUser);

            // 计算一个登陆的凭证
            Token tokenObj = new Token();
            tokenObj.setId(loginUser.getId().toString());
            tokenObj.setInterval(1000 * 60 * 10L);
            tokenObj.setCurrentTime(System.currentTimeMillis());

            // 转换一个JSON对象
            String token = new ObjectMapper().writeValueAsString(tokenObj);
            jsonResult.setToken(token);

            // 设置响应的信息
            jsonResult.setCode(HttpStatus.OK.value());
            // 设置登陆的信息
            jsonResult.setData(loginUser);
        }

        // 返回JSON数据
        return jsonResult;
    }

}
AuthorizationController
package com.xuetang9.frame.uam.web;

import com.xuetang9.frame.uam.util.JsonResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 洋葱
 * @version 1.0.0
 * @date 2020/6/17 17:24
 * @copyright 老九学堂
 */
@RestController
public class AuthorizationController {

    @GetMapping("/no_authorization")
    public JsonResult unAuthor(){
        JsonResult jsonResult = new JsonResult();
        jsonResult.setCode(401);
        jsonResult.setMessage("没有权限访问");
        return jsonResult;
    }
}
ResourceController
package com.xuetang9.frame.uam.web;

import com.xuetang9.frame.uam.domain.Resource;
import com.xuetang9.frame.uam.domain.User;
import com.xuetang9.frame.uam.intercepter.Authorization;
import com.xuetang9.frame.uam.service.ResourceService;
import com.xuetang9.frame.uam.util.JsonResult;
import com.xuetang9.frame.uam.util.NodeMapper;
import com.xuetang9.frame.uam.util.TreeNode;
import com.xuetang9.frame.uam.util.TreeUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

/**
 * 用来访问操作资源信息
 * @author 洋葱
 * @version 1.0.0
 * @date 2020/6/9 16:16
 * @copyright 老九学堂
 */
@RestController
@Slf4j
@Authorization
@CrossOrigin
@RequestMapping("/api")
public class ResourceController {

    @Autowired
    private ResourceService resourceService;


    /**
     * 添加一个资源信息
     * @param resource
     * @return
     */
    @ApiOperation(value = "添加资源",httpMethod = "post",response = JsonResult.class)
    @PostMapping("resources")
    public JsonResult add(@ApiParam Resource resource){
        // 创建一个新增响应的JSON结果
        JsonResult jsonResult = new JsonResult();
        try {
            resourceService.save(resource);
            jsonResult.setCode(HttpStatus.OK.value());
            jsonResult.setData(resource);
        }catch (Exception e){
            jsonResult.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            jsonResult.setError(e);
        }
        return jsonResult;
    }


    @DeleteMapping("resources/{id}")
    public JsonResult remove(@PathVariable int id){
        // 创建一个JSON结果对象
        JsonResult jsonResult = new JsonResult();
        try{
            boolean success = resourceService.deleteById(id);
            if(success){
                jsonResult.setCode(HttpStatus.OK.value());
            }else{
                jsonResult.setCode(10000);
            }
        }catch (Exception e){
            jsonResult.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            jsonResult.setError(e);
        }


        return jsonResult;
    }

    @PostMapping("resources/{id}")
    public JsonResult update(@PathVariable int id, Resource resource){
        log.debug(resource.toString());
        // 创建一个JSON结果对象
        JsonResult jsonResult = new JsonResult();
        try {
            resource.setId(id);
            boolean success = resourceService.updateByIdWithoutNull(resource);
            if(success){
                jsonResult.setCode(200);
            }else{
                jsonResult.setCode(10001);
                jsonResult.setData(resource);
            }
        }catch (Exception e){
            jsonResult.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            jsonResult.setError(e);
        }

        return jsonResult;
    }

    @GetMapping("resources/{id}")
    public JsonResult get(@PathVariable int id){
        JsonResult jsonResult = new JsonResult();
        try {
            Resource resource = resourceService.getById(id);
            jsonResult.setCode(HttpStatus.OK.value());
            jsonResult.setData(resource);
        }catch (Exception e){
            jsonResult.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            jsonResult.setError(e);
        }
        return jsonResult;
    }
    /**
     * 用来返回一个资源树的json数据
     * @return
     */
    @GetMapping("/resources")
    public JsonResult listTree(){
        JsonResult jsonResult = new JsonResult();
        // 获取资源数据的集合
        List<Resource> resources = resourceService.listAll();
        // 把集合数据转换为树形结构
        List<TreeNode> tree = TreeUtils.listToTree(resources, create());
        // 把树形数据保存到JSON数据中
        jsonResult.setData(tree);
        jsonResult.setCode(HttpStatus.OK.value());
        return jsonResult;
    }

    @GetMapping("/menus")
    public JsonResult listMenus(HttpSession session){

        System.out.println("---------- menu ----" + session.getId());
        JsonResult jsonResult = new JsonResult();
        try {
//            User user = (User)session.getAttribute("SESSION_LOGIN");
//            List<Resource> resources = resourceService.listMenus(user.getId());
            List<Resource> resources = resourceService.listMenus(3);
            // 构建一棵树
            List<TreeNode> tree = TreeUtils.listToTree(resources, create());

            jsonResult.setData(tree);
            jsonResult.setCode(HttpStatus.OK.value());

        }catch (Exception e){
            jsonResult.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            jsonResult.setError(e);
            jsonResult.setMessage(e.getMessage());
        }
        return jsonResult;
    }

    @GetMapping("resources/roles/{id}")
    public JsonResult listRoleResources(@PathVariable int id){
        JsonResult jsonResult = new JsonResult();
        List<Resource> list = resourceService.listByRoleId(id);
        jsonResult.setCode(HttpStatus.OK.value());
        jsonResult.setData(list);
        return jsonResult;
    }

    private NodeMapper<Resource> create(){
        return new NodeMapper<Resource>() {
            @Override
            public TreeNode objectMapper(Resource object) {
                TreeNode node = new TreeNode();
                node.setId(object.getId());
                node.setText(object.getName());
                node.setPid(object.getParentId());
                node.setHref(object.getUrl());
                node.setIcon(object.getIcon());
                node.setRaw(object);
                return node;
            }
        };
    }


}
Token
package com.xuetang9.frame.uam.util;

import lombok.Data;

import java.io.Serializable;

/**
 * @author 洋葱
 * @version 1.0.0
 * @date 2020/6/17 18:00
 * @copyright 老九学堂
 */
@Data
public class Token implements Serializable {
    private String id;

    private Long interval;

    private Long currentTime;
}
NodeMapper
package com.xuetang9.frame.uam.util;

/**
 * @author 洋葱
 * @version 1.0.0
 * @date 2020/6/9 16:39
 * @copyright 老九学堂
 */
public interface NodeMapper<T> {

    /**
     * 把一个对象转换为节点的数据对象
     * @param object
     * @return
     */
    TreeNode objectMapper(T object);
}
TreeNode
package com.xuetang9.frame.uam.util;

import lombok.Data;

import java.util.List;

/**
 * 用来定义一个树形节点的数据
 * @author 洋葱
 * @version 1.0.0
 * @date 2020/6/9 16:19
 * @copyright 老九学堂
 */
@Data
public class TreeNode<T> {

    private Integer id;

    private String text;

    private String icon;

    private String href;

    private Integer pid;

    private Integer depth;

    private Boolean expanded;

    private Boolean checked;
    
    private List<TreeNode> children;

    private T raw;

}
TreeUtils
package com.xuetang9.frame.uam.util;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 洋葱
 * @version 1.0.0
 * @date 2020/6/9 16:25
 * @copyright 老九学堂
 */
public class TreeUtils {

    public static <T> List<TreeNode> listToTree(List<T> list, NodeMapper<T> mapper){

        List<TreeNode> nodes = new ArrayList<>();

        for(T row : list){
            // 把集合中的数据转换为树形节点数据
            TreeNode node = mapper.objectMapper(row);
            nodes.add(node);
        }

        // 构建一个具有层次结构的树
        List<TreeNode> tree = new ArrayList<>();
        // 循环获取根节点
        for(TreeNode node : nodes){
            if(node.getPid().equals(0)){
                tree.add(node);
                node.setDepth(0);
                // 每个节点查找子节点
                findChildNodes(node, nodes);
            }
        }

        return tree;
    }

    public static void findChildNodes(TreeNode parentNode, List<TreeNode> nodes){
        for(TreeNode child: nodes){
            // 找到子节点
            if(parentNode.getId().equals(child.getPid())){
                // 判断父节点中的子节点集合是否为空
                if(parentNode.getChildren() == null){
                    parentNode.setChildren(new ArrayList<>());
                }
                // 设置子节点的相关计算数据
                child.setDepth(parentNode.getDepth() + 1);
                // 将子节点添加到父节点的子节点集合中
                parentNode.getChildren().add(child);

                // 查找子节点包含的子节点
                findChildNodes(child, nodes);
            }
        }

    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值