Springboot前後端分離+クロスドメイン+Token検証関連問題と実現コード

6186 ワード

最近、このプロジェクトは前後の分離が必要です。だから、国境を越えた問題に関連して、スクリーンセーバーを使ってユーザーを登録して検証しました。各種問題は二日間解決しました。次は実現過程と解説です。
フロントエンドコード:
ログインページ
var obj = {
	 "loginName":$("#username").val(),
	 "password":$("#password").val(),
	};

$.ajax({  
            type: "POST",   //     
			dataType: "json",
			contentType : 'application/json',
            url:IP+"/loginController/userLogin", //       
            data: JSON.stringify(obj);//   string  		
            async: false,
            error: function(request) {  //    
                 alert("  ");  
            },  
            success: function(data) {  //  	
				 if(data.meta.code === "0"){						
					var Token = data.data.token;			
					 localStorage.setItem("token",Token);	//    ,      		
				     window.location.href="index.html";
				 }
				 else {
					alert(data.meta.message);
				 }
				  
            }  
         });
local Strageライフサイクルは永久であり、これはユーザがブラウザから提供されたUI上でlocal Strage情報をクリアしない限り、これらの情報は永遠に存在することを意味する。保存データのサイズは一般的に5 MBで、クライアント(つまりブラウザ)のみで保存され、サーバとの通信には参加しません。 
ホームページ制作
    var token=localStorage.getItem("token");//       token 
	$.ajax({  
            type: "POST",   //     
			dataType: "json",
			contentType : 'application/json',
            url:IP+"/tResourceController/selectIndexList", //         	
			data:{},
            beforeSend: function(request) {
            request.setRequestHeader("token",localStorage.getItem("token"));},
            error: function(request) {  //    
						alert("     "); 
						window.location.href="login.html";					
            },  
            success: function(data) {  //  
				 alert("  "); 
            }  
         }); 
 
バックエンドコード:
Token工具類
public class TokenUtil {

    /**
     *   token(   token:  -      -  -     )
     * @param username      
     * @return
     */
    public static  String generateToken(String username) {
        StringBuilder token = new StringBuilder();
        // token:
        token.append("token:");
        //       
        token.append(DigestUtils.md5Hex(username) + "-");
        //   
        token.append(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + "-");
        //      111111-999999
        token.append(new Random().nextInt((999999 - 111111 + 1)) + 111111);
        System.out.println("token=>" + token.toString());
        return token.toString();
    }
}
ログインインターフェース
@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping(value = "loginController")
public class LoginController {

    private Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private RedisService redisService;

    @Autowired
    private UserService  userService;

    @PostMapping(value = "userLogin")
    public ResponseResult userLogin(@RequestBody JSONObject jsonObject,
                                    HttpServletRequest request, HttpServletResponse response) {
        String loginName=jsonObject.getString("loginName");
        String password=jsonObject.getString("password");
        /*
            。
            。
                      
            。
            。
         */
            //  token   ,      key      ID   redis 
            String token=TokenUtil.generateToken(loginName);
            redisService.set(token,result.getId());
            HashMap hm = new HashMap<>();
            hm.put("token", token);
            return ResponseResult.success(hm);

    }

   
}
迎撃器 Interceptorクラス
@Component
@CrossOrigin(origins = "*", maxAge = 3600)
public class AccessInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisService redisService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (request.getMethod().equals("OPTIONS")) {
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }
        String token =  request.getHeader("token");
        //  token        
        if(ConstentUtil.isEmpty(redisService.get(token))){
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
スクリーンセーバーWebMvcConfigrer配置クラス
@Configuration
public class MyAdapter implements WebMvcConfigurer {
    private Logger logger = LoggerFactory.getLogger(MyAdapter.class);
    @Bean
    public AccessInterceptor getAccessInterceptor(){
        return new AccessInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getAccessInterceptor()).addPathPatterns("/**");

    }
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedHeaders("Content-Type","X-Requested-With","accept,Origin","Access-Control-Request-Method","Access-Control-Request-Headers","token")
                .allowedMethods("*")
                .allowedOrigins("*")
                .allowCredentials(true);

    }
         まず、ユーザ名、パスワード、認証コードなどを使って、認証URLに入ってtokenを取得し、tokenを取得してから、バックグラウンドと接続を確立して、データを取得することができます。
  • 一般的には、このtokenはcookieやlocal Strageなどに格納されず、グローバル変数の中に入れるだけで、アカウントを変えて登録すると取得できなくなります。現在のページだけに限られており、更新しない場合に使用します。
  • .tokenを可視領域例えばlocal Strageに格納すると、どのような目的で行われますか?ユーザ名とパスワードを覚えてください。Aログイン時の楽屋はtokenだけ確認すれば、確かに登録できます。サイトは安全性を要求していません。大丈夫です。もしウェブサイトが高いと、あなたのtokenは明文に保存できなくなります。手動暗号解読が必要です。