User Login
Introduction
This section introduces user login. After learning it, you can implement login, force login (kick previous session), and duplicate-login prevention.
Example Source Code
see https://github.com/iohao/ionet-examples
path : ionet-cookbook-code
- HallAction
Login
Define protocol class UserMessage to return user info for login business.
- code 7:
flowContext.bindingUserIdis the key login line. It sets real userId on external-server channel. After that, each user request can obtain user-related info via FlowContext.
@ActionController(HallCmd.cmd)
public class HallAction {
...
@ActionMethod(HallCmd.loginVerify)
private UserMessage loginVerify(String jwt, FlowContext flowContext) {
long userId = Math.abs(jwt.hashCode());
boolean success = flowContext.bindingUserId(userId);
ErrorCode.loginFailed.assertTrue(success);
return UserKit.ofUserMessage(userId);
}
}
@ToString
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
public class UserMessage {
long id;
String nickname;
}
You must call this framework method to mark login verification as successful. Otherwise userId cannot be obtained from subsequent FlowContext.
Prevent Duplicate Login
Prevent duplicate login means the same account already online cannot log in again.
- code 3: check whether user is online; if online, trigger assertion.
- code 4: assertion + exception mechanism; if user is online, return error code to requester.
private UserMessage loginVerify(String jwt) {
long userId = Math.abs(jwt.hashCode());
boolean existUser = CommunicationKit.existUser(userId);
ErrorCode.userOnline.assertTrueThrows(existUser);
...
}
Force Login
Force login means the same account is already online, and the online session is kicked out.
- code 3: force specific user offline.
private UserMessage loginVerify(String jwt) {
long userId = Math.abs(jwt.hashCode());
CommunicationKit.forcedOffline(userId);
...
}
UserId
After login, userId can be obtained through FlowContext.
public long hello(FlowContext flowContext) {
return flowContext.getUserId();
}
Can userId support String type?
Business requirement: What if userId is not
long? For example, MongoDBobjectIdisString.
ionet is highly extensible and supports this requirement. Steps:
- Associate user data with a
longid, e.g. Snowflake. - Store
objectIdin meta information - attachment. - Use custom FlowContext.
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
public class MyAttachment {
long userId;
/** MongoDB objectId */
String objectId;
}
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
public class MyFlowContext extends DefaultFlowContext {
MyAttachment attachment;
@Override
public MyAttachment getAttachment() {
if (Objects.isNull(this.attachment)) {
this.attachment = this.getAttachment(MyAttachment.class);
}
return this.attachment;
}
public String getUserIdString() {
var attachment = this.getAttachment(MyAttachment.class);
return attachment.objectId;
}
}