整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          token實現單點登錄

          token實現單點登錄

          sp實際上也是是一個繼承自Servlet接口的java類,實際上它就是一個Servlet,JSP的頁面渲染是在后端完成的,經過tomcat的處理后,把jsp轉為html后,再統一發送給前端(瀏覽器)顯示出來.

          token實現單點登錄

          一般情況下,為了保證安全性,網站會定期更新登錄的detail,例如修改參數名、更新加密(散列)算法等。所以模擬登錄的代碼定期肯定會失效,但是如果網站沒有進行大的更新的話,稍微改一改還是能用的。另外,碰到驗證碼的情況就更難辦了,雖然程序可以一定程度地識別驗證碼字符,但目前很難找到簡單的可以通用的驗證碼識別程序。

          很多朋友有模擬登錄新浪微博抓取數據的需求,其實對于一般的微博數據獲取,如用戶信息、微博內容等,使用微博開放平臺API是更明智的選擇:速度更快,而且節省許多網頁處理的功夫。對于API沒有開放的數據,我們再采用模擬登錄的方法。不多說了,我們直接上代碼:(相關JAR文件地址:https://github.com/leepeng/files)

          package cn.com.leepeng.test;

          import java.text.MessageFormat;

          import java.util.HashMap;

          import java.util.Map;

          import com.gargoylesoftware.htmlunit.BrowserVersion;

          import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;

          import com.gargoylesoftware.htmlunit.WebClient;

          import com.gargoylesoftware.htmlunit.html.HtmlForm;

          import com.gargoylesoftware.htmlunit.html.HtmlPage;

          import net.sf.json.JSONObject;

          import weibo4j.util.CommonHttpProtocolRequestUtil;

          /**

          * 微博模擬登錄獲取AccessToken工具

          *

          * @author Alex.Lee

          * @mail lp@zving.com

          * @date 3rd Apr ,2018

          *

          */

          public class Weibo {

          private static final String AUTH_URL="https://api.weibo.com/oauth2/authorize?client_id={0}&redirect_uri={1}";

          private static final String AUTH_TOKEN="https://api.weibo.com/oauth2/access_token";

          private String clientID;

          private String redirectUri;

          private String username;

          private String password;

          private String clientSecret;

          private String code;

          public Weibo() {

          super();

          }

          ession簡介#

          做過Web開發的程序員應該對Session都比較熟悉,Session是一塊保存在服務器端的內存空間,一般用于保存用戶的會話信息。

          用戶通過用戶名和密碼登陸成功之后,服務器端程序會在服務器端開辟一塊Session內存空間并將用戶的信息存入這塊空間,同時服務器會
          在cookie中寫入一個Session_id的值,這個值用于標識這個內存空間。

          下次用戶再來訪問的話會帶著這個cookie中的session_id,服務器拿著這個id去尋找對應的session,如果session中已經有了這個用戶的
          登陸信息,則說明用戶已經登陸過了。

          使用Session保持會話信息使用起來非常簡單,技術也非常成熟。但是也存在下面的幾個問題:

          • 服務器壓力大:通常Session是存儲在內存中的,每個用戶通過認證之后都會將session數據保存在服務器的內存中,而當用戶量增大時,服務器的壓力增大。
          • Session共享:現在很多應用都是分布式集群,需要我們做額外的操作進行Session共享;
          • CSRF跨站偽造請求攻擊:Session機制是基于瀏覽器端的cookie的,cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊。

          基于token的認證#

          基于token的認證機制將認證信息返回給客戶端并存儲。下次訪問其他頁面,需要從客戶端傳遞認證信息回服務端。簡單的流程如下:

          • 客戶端使用用戶名跟密碼請求登錄;
          • 服務端收到請求,去驗證用戶名與密碼;
          • 驗證成功后,服務端會簽發一個 Token,再把這個 Token 發送給客戶端;
          • 客戶端收到 Token 以后可以把它存儲起來,比如放在 Cookie 里或者 Local Storage 里;
          • 客戶端每次向服務端請求資源的時候需要帶著服務端簽發的 Token;
          • 服務端收到請求,然后去驗證客戶端請求里面帶著的 Token,如果驗證成功,就向客戶端返回請求的數據;

          基于token的驗證機制,有以下的優點:

          • 支持跨域訪問,將token置于請求頭中,而cookie是不支持跨域訪問的;
          • 無狀態化,服務端無需存儲token,只需要驗證token信息是否正確即可,而session需要在服務端存儲,一般是通過cookie中的sessionID在服務端查找對應的session;
          • 無需綁定到一個特殊的身份驗證方案(傳統的用戶名密碼登陸),只需要生成的token是符合我們預期設定的即可;
          • 更適用于移動端(Android,iOS,小程序等等),像這種原生平臺不支持cookie,比如說微信小程序,每一次請求都是一次會話,當然我們可以每次去手動為他添加cookie,詳情請查看博主另一篇博客;
          • 避免CSRF跨站偽造攻擊,還是因為不依賴cookie;

          缺點的話一個就是相比較于傳統的session登陸機制實現起來略微復雜一點,另外一個比較大的缺點是由于服務器不保存 token,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 token 簽發了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

          退出登陸的話,只要前端清除token信息即可。

          基于JWT的token認證實現#

          JWT(JSON Web Token)就是基于token認證的代表,這邊就用JWT為列來介紹基于token的認證機制。

          需要引入JWT的依賴

          <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.8.2</version>
          </dependency>
          

          生成token和驗證token的工具類如下:

          public class JWTTokenUtil {
              //設置過期時間
              private static final long EXPIRE_DATE=30*60*100000;
              //token秘鑰
              private static final String TOKEN_SECRET="ZCfasfhuaUUHufguGuwu2020BQWE";
          
              public static String token (String username,String password){
          
                  String token="";
                  try {
                      //過期時間
                      Date date=new Date(System.currentTimeMillis()+EXPIRE_DATE);
                      //秘鑰及加密算法
                      Algorithm algorithm=Algorithm.HMAC256(TOKEN_SECRET);
                      //設置頭部信息
                      Map<String,Object> header=new HashMap<>();
                      header.put("typ","JWT");
                      header.put("alg","HS256");
                      //攜帶username,password信息,生成簽名
                      token=JWT.create()
                              .withHeader(header)
                              .withClaim("username",username)
                              .withClaim("password",password).withExpiresAt(date)
                              .sign(algorithm);
                  }catch (Exception e){
                      e.printStackTrace();
                      return  null;
                  }
                  return token;
              }
          
              public static boolean verify(String token){
                  /**
                   * @desc   驗證token,通過返回true
                   * @params [token]需要校驗的串
                   **/
                  try {
                      Algorithm algorithm=Algorithm.HMAC256(TOKEN_SECRET);
                      JWTVerifier verifier=JWT.require(algorithm).build();
                      DecodedJWT jwt=verifier.verify(token);
                      return true;
                  }catch (Exception e){
                      e.printStackTrace();
                      return  false;
                  }
              }
              public static void main(String[] args) {
                  String username="name1";
                  String password="pw1";
                  //注意,一般不會把密碼等私密信息放在payload中,這邊只是舉個列子
                  String token=token(username,password);
                  System.out.println(token);
                  boolean b=verify(token);
                  System.out.println(b);
              }
          }
          

          執行結果如下:

          Connected to the target VM, address: '127.0.0.1:11838', transport: 'socket'
          eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXNzd29yZCI6IjEyMyIsImV4cCI6MTU5NzM5Nzc0OCwidXNlcm5hbWUiOiJ6aGFuZ3NhbiJ9.LI5S_nX-YcqtExI9UtKiP8FPqpQW_ccaws2coLzyOS0
          true
          

          關于DecodedJWT這個類,大家可以重點看下,里面包含了解碼后的用戶信息。

          JWT的使用說明#

          客戶端收到服務器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage。

          此后,客戶端每次與服務器通信,都要帶上這個 JWT。你可以把它放在 Cookie 里面自動發送,但是這樣不能跨域,所以更好的做法是放在 HTTP 請求的頭信息Authorization字段里面。

          Authorization: Bearer <token>

          另一種做法是,跨域的時候,JWT 就放在 POST 請求的數據體里面。

          JWT 本身包含了認證信息,一旦泄露,任何人都可以獲得該令牌的所有權限。為了減少盜用,JWT 的有效期應該設置得比較短。對于一些比較重要的權限,使用時應該再次對用戶進行認證。

          為了減少盜用,JWT 不應該使用 HTTP 協議明碼傳輸,要使用 HTTPS 協議傳輸。(或者是對JWT在前后端之間進行加密之后在傳輸)

          關于JWT的一個問題#

          上面生成JWT token的過程關鍵點就是密鑰,假如這個密鑰泄露了,那是不是就可以偽造token了。

          還有就是生產環境的密鑰值,開發的程序員大概率是知道的,怎么防止程序要監守自盜,偽造token值呢?希望有經驗的大佬指教下。

          //token秘鑰
          private static final String TOKEN_SECRET="ZCfasfhuaUUHufguGuwu2020BQWE";
          

          關于上面的問題,@仙湖碼農 給出了一個簡單易懂的方案~

          jwt 來生成token,還有一個玩法,用戶登錄時,生成token的 SecretKey 是一個隨機數,也就是說每個用戶,每次登錄時jwt SecretKey 是隨機數,并保存到緩存,key是登錄賬戶,(當然了,分布式緩存的話,就用Redis,sqlserver緩存等等),總之,客戶端訪問接口是,header 要帶登錄賬戶,和token,服務端拿到登錄賬號,到緩存去撈相應的SecretKey ,然后再進行token校驗??梢苑纻卧靦oken了(這個方案在一定程度上能防止偽造,但是不能防止token泄露被劫持)。

          獲取refresh token的方法#

          • https://www.cnblogs.com/wyt007/p/11459547.html

          主站蜘蛛池模板: 国产在线精品一区二区夜色 | 99久久精品国产高清一区二区| 3d动漫精品啪啪一区二区中文| 日本一区二区在线| 中文无码精品一区二区三区| 伊人久久大香线蕉AV一区二区| 国产精品视频一区二区噜噜| 国产一在线精品一区在线观看| 精品国产一区二区三区久久影院| 极品人妻少妇一区二区三区| 精品乱码一区二区三区四区| 久久青草精品一区二区三区| 国产亚洲一区二区手机在线观看| 午夜福利一区二区三区在线观看 | 无码中文字幕人妻在线一区二区三区| 久久一区二区三区免费播放| 无码少妇一区二区三区浪潮AV| 精品一区二区三区四区在线播放 | 国产一区二区精品久久凹凸| 国产在线不卡一区| 国产亚洲情侣一区二区无| 久久久久人妻一区二区三区vr| 国产日韩综合一区二区性色AV| 精品乱子伦一区二区三区| 国产av成人一区二区三区| 亚洲欧美日韩一区二区三区在线| 国产成人欧美一区二区三区| 国产一区二区三区免费观在线| 亚洲一区在线免费观看| 一区二区三区91| 亚洲AV无码一区二区三区牛牛| 国产三级一区二区三区| 亚洲国产成人久久综合一区| 国产成人一区二区三区高清 | 波多野结衣中文字幕一区二区三区 | 亚欧在线精品免费观看一区| 亚洲国产一区二区视频网站| 蜜臀AV一区二区| 精品国产日产一区二区三区 | 色狠狠色狠狠综合一区| 精品国产亚洲一区二区在线观看|