分散セッション
セッションセッションは、クライアントとサーバーの対話的なプロセスを表し、プロセスが連続することができ、または断続的であってもよいです。フロントセクションはJSESSIONIDがあるでしょうしながら、サーブレット時代(JSP)でたら、サーバーと対話するためのユーザーと、サーバーのTomcatは、ユーザー・セッションを作成し、それぞれの相互作用が運ぶでしょう。このように、取得するためのセッションの後のセッション、長いユーザーが要求を受信したサーバとして、あなたがjsessonid得ることができ、およびIDに応じてメモリに対応するセッションセッションを見つけると、それから、私たちは会話を操作することができます。生きているセッション中に、我々は、ユーザーがウェブサイトを使用することができるようになると思うのセッションの有効期限が切れたら、という状態にあったので、長いサイトを残しているため、ユーザーが対話を停止し、考えることができます。ユーザーのID情報は、我々はセッションによって判断され、セッション情報は、異なるユーザのために保存することができます。
HTTPリクエストステートレス、ユーザーがサーバーに複数の要求を開始したいと思い、サーバは多くの要求が同じユーザからのものであることを知りませんが、これはステートレスです。クッキーの出現は、ユーザレコードの状態を持つことです。共通するのは、サーバーアンドリュースとサーバ間の対話、および相互作用のiOS、彼らは、httpコール・インタフェース・データへの要求を開始するために使用されており、胡ああああ各サーバは、クライアントのステータスを取得することはできませんが、我々は、処理手段を通過することができますユーザーが要求を開始するたびにユーザーIDまたはユーザートークンを運ぶように、そのようなことは、この方法では、ユーザーIDのブランチサーバーまたはトークンが対応するデータを取得するためにさせることができます。各ユーザーの最初の要求の下でサーバが同じユーザから識別することができます。
セッションでTOMCAT、ユーザとサーバの対話後、セッション、ユーザーの情報の保存セッションなので、ユーザーが「状態を持っている」こと、およびサーバと、このような特別な関係を維持するために、各クライアントがあり、状態を持つことですこれは、コンテナによって管理され、このセッションのセッションは異なるユーザーがサーバーにアクセスするこの方法は、メモリ空間に保存されるので、長いセッションが誰であるかを知ることができます。Tomcatのセッションは、http要求が状態になるようにしても表示されます。ユーザーは、サーバーとの対話にない場合、セッションは彼のライフサイクルを終了し、時間を有効期限が切れます。
トークンを生成
一般利用者が対話処理に入るための使用シナリオでは、通常、ユーザのためのユーザ登録およびログイン・トークンを作成する最初のステップでは、これは
public UserVO convertUserVO(Users user) {
//使用uuid生成一个随机的唯一的序列码,然后根据userId保存到redis中去
String uniqueToken = UUID.randomUUID().toString().tirm();
redisTemplate.opsForValue().set(REDIS_USER_TOKEN + ":" + userId, uniqueToken);
//一般在我们完成注册或者登录后,在验证完用户名和密码后都会返回一个包含用户信息的user对象
//而同时我们需要生成一个user——token和user对象一同返回到方法调用方,因为这个token后面是要设置到
//cookie里面的
UserVO userVO = new UserVO();
BeanUtils.copyProperities(user, userVO);
userVO.setUserToken(uniqueToken );
return userVO;
}
セッションインターセプタ
私たちは、コントローラパッケージ内のサブパケットインターセプタを作成し、私たちのインターセプタを定義するクラスを作成します
public class UserTokenInterceptor implements HandlerInterceptor {
@Autowired
private RedisOperator redisOperator;
public static final String REDIS_USER_TOKEN = "redis_user_token";
//在请求到达controller前的阶段
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//这需要后端和前段协调一下,让前段将cookie中的信息解析到header中在向后端发起请求
String userToken = request.getHeader("headerUserToken");
String userId = request.getHeader("headerUserId");
if (StringUtils.isBlank(userToken) || StringUtils.isBlank(userId)) {
returnErrorResponse(response, JSOMResult.errorMsg("请登录");
return false;
} else {
String token = RedisOperator.get(REDIS_USER_TOKEN + ":" + userId);
//这就等于在我们服务器中没有该用户的session,或者其session已经超时了
if (StringUtils.isBlank(token)) {
returnErrorResponse(response, JSOMResult.errorMsg("请登录");
return false;
} else {
//服务器中的session信息和用户cookie中的不同,这样可能是因为用户异地登录了的原因
if (!token.equals(userToken)) {
returnErrorResponse(response, JSOMResult.errorMsg("请重新登录");
return false;
}
}
}
return true;
}
private void returnErrorResponse(HttpServletResponse response, JSONResult result) {
outputStream = null;
try{
response.setCharacterEncoding("utf-8");
response.setContentType("text/json");
out = response.getOutputStream();
out.write(JsonUtils.objectToJson(result).getBytes("utf-8");
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//下面省略了postHandler和afterComplete两个方法的内容,因为我们暂时用不上
}
あなたはSpringMVCを使用している場合、直接書き込みのXML設定ファイルである種類の構成のものを、ここだ
WebMvcConfig内部クラスを作成し、コントローラパッケージ内のconfigサブパッケージを作成します
/**
* 这个类是要实现WebMvcConfigurer接口的,里面有很多方法,可以自行选择,包括静态资源的映射也是用他
* 因为拦截器相应注解来自动注入容器,所以这里用@Bean来生成
* 在拦截器添加器中用注册器先调用这个Bean方法生成
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public UserTokenInterceptor userTokenInterceptor() {
return new UserTokenInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userTokenInterceptor())
.addPathPattern("/shopcart/add")
.addPathPattern("/shopcart/*")
.addPathPattern("/address/list")
.addPathPattern("/address/add")
.addPathPattern("/address/*")
.addPathPattern("/orders/*")
.addPathPattern("/userInfo/*")
.addPathPattern("/myorders/*")
.excludePathPattern("/myorders/deliver")
.excludePathPattern("/orders/notifOrderPaid");
WebMvcConfigurer.super.addInterceptors(registry);
}
}