摘要:也做了權限控制,訪問的請求必須要帶上事先認證后獲取的才可以。認證的話就在中進行的,會獲取請求的進行驗證,如果成功了可以得到中的用戶信息,本文的核心就是講解如何將用戶信息用戶優雅的傳遞給接口。
背景我們有一個Web項目,這個項目提供了很多的Rest API。也做了權限控制,訪問API的請求必須要帶上事先認證后獲取的Token才可以。
認證的話就在Filter中進行的,會獲取請求的Token進行驗證,如果成功了可以得到Token中的用戶信息,本文的核心就是講解如何將用戶信息(用戶ID)優雅的傳遞給API接口(Controller)。
方式一(很挫)我們在Filter中進行了統一攔截,在Controller中獲取用戶ID的話,仍然可以再次解析一遍Token獲取用戶ID
@GetMapping("/hello")
public String test(HttpServletRequest request) {
String token = request.getHeader("token");
JWTResult result = JWTUtils.checkToken(token);
Long userId = result.getUserId();
}
方式二(優雅)
方式一需要重新解析一遍Token, 浪費資源。我們可以直接將Filter中解析好了的用戶ID直接通過Header傳遞給接口啊。
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String token = request.getHeader("token");
JWTResult result = JWTUtils.checkToken(token);
Long userId = result.getUserId();
HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(httpRequest) {
@Override
public String getHeader(String name) {
if (name.equals("loginUserId")) {
return userId .toString();
}
return super.getHeader(name);
}
};
chain.doFilter(requestWrapper, httpResponse);
}
接口中直接從Header中獲取解析好了的用戶ID:
@GetMapping("/hello")
public String save2(HttpServletRequest request) {
Long userId = Long.parseLong(request.getHeader("loginUserId"));
}
方式三(很優雅)
通過Header傳遞確實很方便,但如果你有代碼潔癖的話總會覺得怪怪的,能不能不用Header方式,比如說我就在方法上定義一個loginUserId的參數,你給我直接注入進來,這個有點意思哈,下面我們來實現下:
GET參數方式在Filter中追加參數:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String token = request.getHeader("token");
JWTResult result = JWTUtils.checkToken(token);
Long userId = result.getUserId();
HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(httpRequest) {
@Override
public String[] getParameterValues(String name) {
if (name.equals("loginUserId")) {
return new String[] { userId .toString() };
}
return super.getParameterValues(name);
}
@Override
public Enumeration getParameterNames() {
Set paramNames = new LinkedHashSet<>();
paramNames.add("loginUserId");
Enumeration names = super.getParameterNames();
while(names.hasMoreElements()) {
paramNames.add(names.nextElement());
}
return Collections.enumeration(paramNames);
}
};
chain.doFilter(requestWrapper, httpResponse);
}
接口中直接填寫參數即可獲取:
@GetMapping("/hello")
public String save2(String name, Long loginUserId) {
// loginUserId 就是Filter中追加的值
}
對于post請求,也可以用這種方式:
@PostMapping("/hello")
public String save2(User user, Long loginUserId) {
}
可是往往我們在用post請求的時候,要么就是表單提交,要么就是json體的方式提交,一般不會使用get方式參數,這也就意味著這個loginUserId我們需要注入到對象中:
先創建一個參數實體類:
public class User { private String name; private Long loginUserId; }
先模擬表單提交的方式,看看行不行:
@PostMapping("/hello")
public User save2(User user) {
return user;
}
用PostMan測試一下,表單方式是直接支持的:
再次試下Json提交方式:
@PostMapping("/hello")
public User save2(@RequestBody User user) {
return user;
}
看下圖,失敗了,得重新想辦法實現下
只需要在HttpServletRequestWrapper中重新對提交的內容進行修改即可:
@Override
public ServletInputStream getInputStream() throws IOException {
byte[] requestBody = new byte[0];
try {
requestBody = StreamUtils.copyToByteArray(request.getInputStream());
Map map = JsonUtils.toBean(Map.class, new String(requestBody));
map.put("loginUserId", loginUserId);
requestBody = JsonUtils.toJson(map).getBytes();
} catch (IOException e) {
throw new RuntimeException(e);
}
final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
}
到此為止,我們就可以直接將Token解析的用戶ID直接注入到參數中了,不用去Header中獲取,是不是很方便。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7152.html
摘要:也做了權限控制,訪問的請求必須要帶上事先認證后獲取的才可以。認證的話就在中進行的,會獲取請求的進行驗證,如果成功了可以得到中的用戶信息,本文的核心就是講解如何將用戶信息用戶優雅的傳遞給接口。背景 我們有一個Web項目,這個項目提供了很多的Rest API。也做了權限控制,訪問API的請求必須要帶上事先認證后獲取的Token才可以。 認證的話就在Filter中進行的,會獲取請求的Token進行...
摘要:也做了權限控制,訪問的請求必須要帶上事先認證后獲取的才可以。認證的話就在中進行的,會獲取請求的進行驗證,如果成功了可以得到中的用戶信息,本文的核心就是講解如何將用戶信息用戶優雅的傳遞給接口。背景 我們有一個Web項目,這個項目提供了很多的Rest API。也做了權限控制,訪問API的請求必須要帶上事先認證后獲取的Token才可以。 認證的話就在Filter中進行的,會獲取請求的Token進行...
摘要:認證服務器,即服務提供商專門用來處理認證的服務器。它與認證服務器,可以是同一臺服務器,也可以是不同的服務器。客戶端使用上一步獲得的授權,向認證服務器申請令牌。認證服務器對客戶端進行認證以后,確認無誤,同意發放令牌。 最近想做個小程序,需要用到授權認證流程。以前項目都是用的 OAuth2 認證,但是Sanic 使用OAuth2 不太方便,就想試一下 JWT 的認證方式。這一篇主要內容是 ...
摘要:的統一認證授權是下面的一個簡單,易用的權限框架,對于單體應用來講,完全能夠極好的,快速的滿足權限的需求,所以一般在做項目的時候,都會成為開發者的首選。 Shiro的統一認證授權 Shiro是Apache下面的一個簡單,易用的Java權限框架,對于單體應用來講,Shiro完全能夠極好的,快速的滿足權限的需求,所以一般在做項目的時候,Shiro都會成為開發者的首選。 可是,如果你需要做第二...
摘要:暑假的時候在學習了并成功運用到了項目中。這是提供的一個安全權限控制框架,可以根據使用者的需要定制相關的角色身份和身份所具有的權限,完成黑名單操作攔截無權限的操作。用戶通過登陸操作獲得我們返回的并保存在本地。 暑假的時候在學習了 Spring Security 并成功運用到了項目中。 在實踐中摸索出了一套結合 json + jwt(json web token) + Spring Boo...
閱讀 713·2023-04-25 19:43
閱讀 3910·2021-11-30 14:52
閱讀 3785·2021-11-30 14:52
閱讀 3852·2021-11-29 11:00
閱讀 3783·2021-11-29 11:00
閱讀 3869·2021-11-29 11:00
閱讀 3558·2021-11-29 11:00
閱讀 6105·2021-11-29 11:00