1、登录
1.1 获取token令牌
登录时的ajax请求:
 
后端路由配置处理:
登录的路由配置
作用:把oAuth2.0颁发的token存储到redis中
package com.powernode.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.powernode.constant.GatewayConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import reactor.core.publisher.Mono;
import java.time.Duration;
/**
 * 登录的路由配置
 * 作用:把oAuth2.0颁发的token存储到redis中
 */
@Configuration
public class LoginRouteConfig {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 代码方式的路由存储token
     *
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator loginRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("auth-server-route", r -> r.path("/oauth/token").filters(
                        f -> f.modifyResponseBody(String.class, String.class, (exchange, s) -> {
                            //s为响应的结果,类型为json,结构为{"access_token","expires_in"}
                            //将响应的json数据转换为json对象
                            JSONObject jsonObject = JSON.parseObject(s);
                            //查看是否包含access_token
                            if (jsonObject.containsKey("access_token")) {
                                //有:存放到redis中
                                //获取token值和过期时间
                                String access_token = jsonObject.getString("access_token");
                                Long expires_in = jsonObject.getLong("expires_in");
                                //将获取的值存放到redis中
                                stringRedisTemplate.opsForValue().set(GatewayConstant.TOKEN_PREFIX+access_token,"", Duration.ofSeconds(expires_in));
                            }
                            return Mono.just(s);
                            //uri是路由的目的地,(lb://auth-server是授权中心服务名称)
                        })).uri("lb://auth-server"))
                .build();
    }
}
Redis拿到的缓存:
 
前端返回响应的JSON数据,与Redis一致:
 
 解析部分JSON数据:
 
前端代码处理token,放进cookie中:
1.2 根据用户标识获取菜单和权限集合
前端发出的 ajax 请求:
 
.
利用mybatis的一个插件,生成相应的代码:
 
 
 .
会生成domain实体类,service接口及实现类,mapper接口及实现xml文件:
 
 
 .
 创建一个controller类:controller.SysMenuController
package com.powernode.controller;
import com.powernode.domain.SysMenu;
import com.powernode.service.SysMenuService;
import com.powernode.utils.AuthUtil;
import com.powernode.vo.MenuAndAuth;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Api(tags = "菜单权限接口管理")
@RequestMapping("sys/menu")
@RestController
public class SysMenuController {
    @Autowired
    private SysMenuService sysMenuService;
    @ApiOperation("根据用户标识查询菜单和权限集合")
    @GetMapping("nav")
    public ResponseEntity<MenuAndAuth> loadUserMenuAndAuth() {
        //获取用户标识
//        String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        String userId = AuthUtil.getLoginUserId();
        //根据用户标识查询菜单和权限集合
        //获取权限集合
        Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
        List<String> auths = authorities.stream().map(Objects::toString).collect(Collectors.toList());
        //根据用户id查询菜单集合
        List<SysMenu> sysMenuList = sysMenuService.selectSysMenuListByUid(userId);
        //成功,并没有数据返回
//        return ResponseEntity.ok().build();
        //成功,有数据返回
//        return ResponseEntity.ok(数据);
        MenuAndAuth menuAndAuth = new MenuAndAuth(sysMenuList,auths);
        return ResponseEntity.ok(menuAndAuth);
    }
//    sys/menu/table
    @ApiOperation("查询系统权限集合")
    @GetMapping("table")
    @PreAuthorize("hasAuthority('sys:menu:list')")
    public ResponseEntity<List<SysMenu>> loadSysMenuList() {
        List<SysMenu> list = sysMenuService.list();
        return ResponseEntity.ok(list);
    }
}
其中:
 1、创建一个vo.MenuAndAuth类:
 (用于返回菜单和权限的集合对象)
package com.powernode.vo;
import com.powernode.domain.SysMenu;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ApiModel("菜单和权限对象")
public class MenuAndAuth {
    @ApiModelProperty("菜单集合")
    private List<SysMenu> menuList;
    @ApiModelProperty("权限集合")
    private List<String> authorities;
}
2、前端代码,响应的数据属性名,也要和后端封装返回的菜单和权限属性名相同:
3、封装获取用户标识工具类:
package com.powernode.utils;
import org.springframework.security.core.context.SecurityContextHolder;
public class AuthUtil {
    public static String getLoginUserId() {
        return SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
    }
}


















