Session && Cookie

Before, i only knew session is used to store data in the server and cookie is used to store data in the Client. However, it is far from enough at work.

For example:

If the user is logged in, we need to use session to store user’s information. Meanwhile, the server **automatically **storedssessionid within cookie and sends the cookie to the Client. We can see the set_Cookie attribute in the response header. and the Cookie:JSESSIONID=.... attribute in the request header.

notice:

the programmer is not need to operate the sessionId in the cookie , the browser will automatically maintain cookie.

Unless the cookie is set by yourself.

A session is a way to bind a browser session to a session server side. If you use different browsers (or privacy mode) you should be served a new session.

method : add cookie in the back end on your own initiative

response.setContentType("text/html;charset=utf-8");

HttpSession session = request.getSession();
session.setAttribute("data", "saveDat");
//save sessionid in cookie

Cookie cookie = new Cookie("JSESSION", session.getId());

//set a valid time

cookie.setMaxAge(60*20);

response.addCookie(cookie);



//when its first time to create session in the client, the server will create a new Session. or get the old sessionId.
String data = (String)request.getSession().getAttribute("data");

Properties: name, value, maxAge, secure, path, domain, comment, version HttpOnly.

maxAge: valid time. unit: second. if the value is negative number, it means the cookie is temporary . When the browser closes, the cookie is invalid. if the value is equal to 0, it means the cookie will be deleted. The default value is -1

secure: The HTTP Protocol is not only stateless, but also insecure. The data using HTTP Protocol spreads directly on the network without any encryption. when cookie.setSecure(true), the browser will spread the data with some secure protocols like SSL and HTTPS notice: it does not encrypt cookie content.

The following code will output all cookies

<script>document.write(document.cookie);</script>

so we can set HttpOnly property so that js can not read cookie . It can effectively prevent XSS attack

reference:

set httpOnlyattribute using Filter

session hijack

distributed session and session theory

Cross-origin resource sharing (CORS)

For security reasons, browsers prohibit AJAX calls to resource residing outside the current origin. Cross-origin resource sharing (CORS) is a W3C specification implemented by most browsers that allows you to specify in a flexible way what kind of cross domain requests are authorized, instead of using some less secured and less powerful hacks like IFRAME or JSONP ——–spring website && CORS

Three key points: the same protocol, the same port , the same domain.

W3C specification

Access-Control-Allow-Origin : return the value the origin request header, “*”, “null”.

​ notice: string “null”

Access-Control-Allow-Credentials: indicate whether the response to request can be exposed.

Access-Control-Max-Age: valid time

Access-Control-Allow-Methods : POST, GET , OPTIONS etc. notice : use OPTIONS method for preflight request.

……..

about preflight request —chinese description

how to do?

solution 1: rewrite route did not try it…

solution 2: set tomcat did not try it….

solution 3:

angular6: Interceptor

import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpErrorResponse } from '@angular/common/http';
import {Observable, throwError} from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { ActivatedRoute, Router } from '@angular/router';
import { CookieService } from "ngx-cookie-service";
@Injectable()
export class WithcredentialsInterceptor implements HttpInterceptor {
  constructor(
    private _cookieService:CookieService,
    private router: Router,

  ){}
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    var request;

    var temp = req.body;
    if(req.url.indexOf('backend/')>-1 && req.url.indexOf('backend/user/login') == -1){
      console.log(req.url,'cookie ', this._cookieService.get("SHGJSESSIONID"))
      temp.createTime = null;
      temp.updateTime = null;
      request = req.clone({
        withCredentials: true,
        setHeaders:{"Content-Type": "application/x-www-form-urlencoded"},
        // body:JSON.stringify(req.body)
        body:temp
      });
    }else{
      request = req;
    }
    return next.handle(request).pipe(retry(3)).pipe(catchError((err : any) =>{
           if (err instanceof HttpErrorResponse) {
            if (err.status === 401) {
              this.router.navigate(['/login']);
            }
            return  throwError(err);
        }
      }
    ));
}}
notice:withCredential: true; Content-Type: “application/x-www-form-urlencoded”.

if ContentType is application/json , it will not work. reason:important

spring boot:


public class SecurityInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.setHeader("Access-Control-Allow-Credentials","true");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
        HttpSession session = request.getSession();

        if (session.getAttribute(WebSecurityConfig.SESSION_KEY) != null) {
            return true;
        } else {
            Cookie[] cookies = request.getCookies();
            if(cookies != null){
                for(Cookie cookie : cookies){
                    if(session.getId().equals(cookie.getValue())){
                        return true;
                    }
                }
            }


            response.setStatus(401);
//            response.setHeader("Cache-Control", "no-store");
//            response.setDateHeader("Expires", 0);
//            response.setHeader("WWW-authenticate", "Basic Realm=\"请先登录系统\"");
            return false;
        }
//        return true;

    }

}



//we need to pass sessionId  to angular. because if the cookie is disabled.
// save store sessionId within cookie in the angular.
//reference:https://blog.csdn.net/fwk19840301/article/details/80675547
//https://blog.csdn.net/woshiyeguiren/article/details/79194003
notice:

www-authenticate: i do not suggest setting the attribute. if you set it and your response status is 4xx, the browsers will pop up a login prompt.

reference:

https://stackoverflow.com/questions/86105/how-can-i-suppress-the-browsers-authentication-dialog
这里写图片描述

some people write the following:

@Configuration
public class WebSecurityConfig extends WebMvcConfigurerAdapter {

    /**
     * 登录session key
     */
    public static final String SESSION_KEY = "user";

    @Bean
    public SecurityInterceptor getSecurityInterceptor() {
        return new SecurityInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration addInterceptor = registry.addInterceptor(getSecurityInterceptor());

        // 排除配置
        addInterceptor.excludePathPatterns("/backend/user/login");
        addInterceptor.excludePathPatterns("/backend/user/success");
        addInterceptor.excludePathPatterns("/backend/user/loginout");
        addInterceptor.excludePathPatterns("/login**");

        // 拦截配置
        addInterceptor.addPathPatterns("/backend/**");
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")
                .allowCredentials(true).maxAge(3600);
    }
}

addCorsMappings method does not work. Access-Control-Allow-Origin should not be ‘*’; so need a filter or interceptor to set Access-Control-Allow-Origin

reference:

http://www.ruanyifeng.com/blog/2016/04/cors.html

https://blog.csdn.net/qq779446849/article/details/53102925

https://blog.csdn.net/saytime/article/details/74937204

BUG

Because Content-Type is application/x-www-form-urlencoded,

For application/x-www-form-urlencoded, the body of the HTTP message sent to the server is essentially one giant query string – name/value pairs are separated by the ampersand (&), and names are separated from values by the equals symbol (=). An example of this would be:

MyVariableOne=ValueOne&MyVariableTwo=ValueTwo

When you send the value encrypted by base64 with jsonString format, you may meet a parse bug.

example:

     var data={
           password: btoa((this.validateForm.controls['password'].value)),
           oldPassword: btoa((this.validateForm.controls['oldPassword'].value)),
           userName: this.username
        }
          this.indexService.changePassword(data).subscribe(
          (response :any) =>{
            this.isOkLoading = false;
            this.isVisible = false;
            if(response.status == environment.SUCCESS_STATUS){

              this.router.navigate(["login"]);
            }else{
              this.validateForm.reset();
              this._message.error("修改失败");
            }
          }
        )
    //angular6  base64  ---btoa

when the password is 1234567 , the value encrypted by base64 will end with the double equals symbols ( = =),

and the browsers will parse == into :=
这里写图片描述

这里写图片描述
so i have to do this:

var data ="password="+btoa((this.validateForm.controls['password'].value))+"&"+"oldPassword="+btoa((this.validateForm.controls['oldPassword'].value))
             +"&" +"userName="+this.username;

and the browsers will parse the value into key/value pairs.

like :

FormData:

password:....

oldPassWord: .....

userName:.....
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值