1. 程式人生 > 程式設計 >Vue+Vuex實現自動登入的知識點詳解

Vue+Vuex實現自動登入的知識點詳解

在之前實現的版本中,如果你進行測試,可以看到在瀏覽器的local Storage中,確實裡面有了我們加入的Authorization,而且如果沒有登入的話,直接訪問主頁會進入登入頁面。但其實有好幾個問題並沒有解決:

一、我們所加的Authorzation其實並不是從伺服器傳過來的,而是自己的測試:只要伺服器傳過來了200的響應狀態碼,我們就自己加上固定的Authorization

二、我們重新進入的時候,判斷條件是隻要有Authorization就可以直接進入了,但其實應該提交給伺服器判斷這個Authorization是否在資料庫中,才可以。

基於以上兩點,我們對程式碼進行修改:

首先就是,我們獲取的token應該是從伺服器獲取的,而不是自己給定,因此直接在伺服器上接收到資訊後修改:

@RequestMapping(value = "/login",method = RequestMethod.POST)
  public RespBean login(
      @RequestBody UserLogin userLogin,Model model
  ){
    if (userService.check(userLogin)){
      String token = UUID.randomUUID().toString();
//      System.out.println(token);
      userService.autoLog(userLogin,token);
      return new RespBean("success","登入成功",token);

    }else{
      return new RespBean("fail","登入失敗");
    }
  }

這裡使用uuid直接生成隨機的token,為了用respBean傳遞回去資料,因此傳遞回去的物件除了狀態資訊和訊息之外,還需要多加一個token:

RespBean物件程式碼為:

  public class RespBean {
  private String status;
  private String msg;
  private String token = null;
}

各種方法自己加上就好了。

如果仔細的話,會發現我們傳進來的引數好像跟上一次的不一樣了,上一次傳遞了兩個用@RequestParam修飾的賬號密碼的String型別的物件,而這一次直接傳遞了一個UserLogin的物件,這是因為我覺得如果要接收表單等資訊的話,每一個都使用這樣的一個個引數會顯得接收引數很多,而且如果要修改接收的數值的話,可能需要很多地方都要修改,複用性太差了。

第二個原因是我們的Controller層應該只是最大限度的邏輯表示,而具體怎麼新增使用者、怎麼鑑別使用者是否登入等資訊,完完全全應該交給下層的Service層呀Mapper層呀去做,但如果接收的是這樣的password、username等數值的話,呼叫下一層的時候,我們還需要把這些數值直接放入,否則就要在Controller層對資料進行操作,這就破壞層次結構了。

所以,為了解決這個問題,我們可以把所有表單中需要用到的資料單獨封裝成一個物件,這個物件就專門用來接收web的資料以及在各個層之間流轉:

java @Data public class UserLogin { private String username; private String password; }把,
這裡的@Data註解就是lombok的註解,可以讓我們不用再去建立get、set等方法了。這樣建立完物件以後,我們的登入操作就可以直接將這樣的物件拿來使用了。

但是,如果你是跟著做下來的,就會遇到跟我一樣的問題:登入的時候會報錯:

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'username': was expecting (JSON String,Number,Array,Object or token 'null','true' or 'false'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'username': was expecting (JSON String,'true' or 'false')

大概的意思就是說,我們接受的跟發出的不大一樣,對應不上,而這樣的原因是:我們當時為了使用get和@RequestParam方法,在api.js中,把獲取到的json資料格式,變成了json字串的格式了,所以就不能使用@RequestBody這樣一個接收json物件的方法來接收了。

因此上一個程式中的api.js改為:

export const postRequest = (url,params) => {
 return axios({
  method: 'post',url: `${base}${url}`,data: params,// transformRequest: [function (data) {
  //  // Do whatever you want to transform the data
  //  let ret = ''
  //  for (let it in data) {
  //   ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
  //  }
  //  return ret
  // }],headers: {
   'Content-Type': 'application/json;charset=UTF-8'
  }
 });
}

詳細的可以看一下這個文章@RequestBody和@RequestParam的區別

而第二點,關於如何實現鑑別token,就是在路由之前的那個方法上,加上傳遞給伺服器以及接收相應資訊進行操作:

router.beforeEach((to,from,next)=>{
 if(to.path ==='/login'){
  next();
 }else {
  let token = localStorage.getItem('Authorization');

  if(token ===null || token ===''){
   next('/login');
  }else {
   getRequest('/autoLog',{
     token:token
   }).then(resp=>{
    if(resp.status == 200){
      var json = resp.data;
      if(json.status=='success'){
       next();
      }else{
       // next('/login');
      }
    }else{
     alert('請求失敗','失敗!');
    }
   })
  }
 }
});

伺服器的處理也就很簡單了,跟上面登入其實是差不多的,就不再列舉出來了

以上就是Vue+Vuex實現自動登入的知識點詳解的詳細內容,更多關於Vue+Vuex實現自動登入的資料請關注我們其它相關文章!