统一用户登录中心:
•1 用户中心服务
•2 缓存用户信息、认证Token 到 Redis
•3 在Redis设置Session超时时间(15 min)
•4 使用Zuul进行校验
图解:具体功能容后实现
简单标注一下顺序,回复友人,并不非常严谨:
简单模拟验证token:
用到userservice与zuul-a:(具体内容请见上一篇015 SpringCloud_Zuul网关(一))
userservice-------------------->UserController:
package com.cc.springcloud.api;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@RequestMapping(value="/user")
public String user() throws Exception{
return "-----user-----";
}
//用户授权及认证:目前主流的是jwt、oauth2方式,但相对不灵活;最优的方式就是自己实现。
@RequestMapping(value="/coupon")
//验证token要传入相关参数Header,正常要将Header封装为json对象
public String coupon(@RequestHeader("token") String token,@RequestHeader("Level") String level) throws Exception{
System.out.println("token----->"+token+",user level----->"+level);
return "-----get coupon!-----";
}
}
-----------------------------------------------------------------------------------------------------------------------------------
zuul-a--------------------------------->MyZuulFilter:
package com.cc.springcloud;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
@Component //必须加入此注解,让spring容器可识别
public class MyZuulFilter extends ZuulFilter{
/**
* shouldFilter则表示该filter是否需要执行
* true表示请求走此过滤器,开启
* false表示请求不在此过滤器,关闭
*/
@Override
public boolean shouldFilter() {
// TODO Auto-generated method stub
//return false;
return true;
}
/**
* filterOrder表示执行的优先级,值越小表示优先级越高
* zuul-filer可以写多个,用此方法来标示执行的优先级
*/
@Override
public int filterOrder() {
// TODO Auto-generated method stub
return 0;
}
/**filterType表示filter执行的时机
* pre:在请求被路由之前调用
* routing: 在请求被路由之中调用
* post: 在请求被路由之后调用
* error: 处理请求发生错误时调用
*/
@Override
public String filterType() {
// TODO Auto-generated method stub
return "pre";
}
/**
* 真正执行Filter逻辑的方法
*/
@Override
public Object run() throws ZuulException {
/**
RequestContext ctx = RequestContext.getCurrentContext();
//可以通过com.netflix.zuul.context.RequestContext直接获取HttpServletRequest
HttpServletRequest request = ctx.getRequest();
System.out.println("----------uri:------------"+request.getRequestURI());
*/
/**
* 获取并验证token有效性
*/
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
//前端将token存入Header中(惯用约定)
String token = request.getHeader("x-token");
//如果token不为空并且token等于1234
if(!StringUtils.isBlank(token) && "1234".equals(token)) {
//设置传入后台token内容
ctx.addZuulRequestHeader("token", token);
//设置当前用户的角色信息、用户等级...
ctx.addZuulRequestHeader("Level", "10");
}else{
System.out.println("-----access token error!-----");
//无响应信息
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody("-----token is error!-----");
//阻止向下游执行
return null;
}
return ctx;
}
}
-----------------------------------------------------------------------------------------------------------------------------------
启动测试:
浏览器直接访问被拦截;使用postman进行测试!
验证通过!