IOS implements refresh access token in OAuth2.0 and re-request data operations, iosoauth2.0
I. Brief Introduction
OAuth2.0 is the next version of the OAuth protocol. It is often used for mobile client development and is a safer mechanism. In OAuth 2.0, the server will issue a short-lived access token and a long-lived refresh token. This allows the client to obtain a new access token without further operations, and also limits the validity of the access token. That is, when the access token sent by the sever expires, the client will call the method to send the access token and refresh token to the server, and the server will return the new access token and refresh token.
II. Application scenarios
After a user logs on, the server will issue an access token with a valid time and a refresh token with a long life cycle. When a user makes other network requests, the access token is added to the Request body (refresh token is not required ). If the access token expires during the request, the corresponding status code is returned. In this case, a callback method is called. In the callback method body, the original access token and refresh token are sent to the server to obtain the new access token and refresh token. Then add the new access token to the Request body and reload the network request.
Restrict the validity period of the access token to improve security. You cannot detect the operation of re-obtaining and re-loading requests after the access token expires. This mechanism is particularly common in clients such as QQ and Weibo.
Iii. instance code
(1) This class inherits the AFHTTPSessionManager class in AFNetworking and overwrites the methods in it.
NetWorkCallBack. h:
1 #import <Foundation/Foundation.h>2 #import <AFNetworking.h>3 @interface NetWorkCallBack : AFHTTPSessionManager4 5 @end
NetWorkCallBack. m:
1 # import "NetWorkCallBack. h "2 # import <SSKeychain. h> 3 @ implementation NetWorkCallBack 4 5-(NSURLSessionDataTask *) dataTaskWithRequest :( handle *) urlRequest completionHandler :( void (^) (NSURLResponse * response, id responseObject, NSError * error )) originalCompletionHandler {6 7 // create a completion block that wraps the original 8 void (^ authFailBlock) (NSURLResponse * response, id respo NseObject, NSError * error) = ^ (NSURLResponse * response, id responseObject, NSError * error) 9 {10 NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response; 11 if ([httpResponse statusCode] = 401) {12 13 // if access token expires, an error is returned. Call this block14 dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_LOW, 0 ), ^ {15 16 // call the refreshAccesstoken method to refresh the access token. 17 [self refreshAccessToken: ^ (AFHTTPRequestOperation * operation) {18 // access the new access token. Here I used KeyChain access 19 NSDictionary * headerInfo = operation. response. allHeaderFields; 20 NSString * newAccessToken = [headerInfo objectForKey: @ "access-token"]; 21 NSString * newRefreshToken = [headerInfo objectForKey: @ "refresh-token"]; 22 [SSKeychain deletePasswordForService: @ "<key>" account: @ "access-token"]; 23 [SSKeycha In deletePasswordForService: @ "<key>" account: @ "refresh-token"]; 24 [SSKeychain setPassword: newaccesen en forService: @ "<key>" account: @ "access-token"]; 25 [SSKeychain setPassword: newRefreshToken forService: @ "<key>" account: @ "refresh-token"]; 26 27 // Add the new access token to the original request body and resend the request. 28 [urlRequest setValue: newaccesen en token: @ "access-token"]; 29 30 minutes * originalTask = [super dataTaskWithRequest: urlRequest completionHandler: originalCompletionHandler]; 31 [originalTask resume]; 32}]; 33}); 34} else {35 NSLog (@ "no auth error"); 36 originalCompletionHandler (response, responseObject, error); 37} 38 }; 39 40 NSURLSessionDataTask * stask = [super dataTaskWithR Equest: urlRequest completionHandler: authFailBlock]; 41 42 return stask; 43 44}; 45 46 47/* 48 * method for obtaining a new token. For more information about how to obtain custom information, see AFNetWorking AFHTTPRequestOperation class 49 */50-(void) refreshaccesen en :( void (^) (AFHTTPRequestOperation * responseObject )) refresh {51 NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL: @ "<yourURL>"]; 52 53 [request setValue: @ "application/json" forHTTPHeaderField: @ "Content-Type"]; 54 55 // send the original access token and refresh token to the server to obtain the new token56 NSString * accessToken = [SSKeychain passwordForService: @ "<key>" account: @ "access-token"]; 57 NSString * refreshToken = [SSKeychain passwordForService: @ "<key>" account: @ "refresh-token"]; 58 59 [request setValue: accessToken forHTTPHeaderField: @ "access-token"]; 60 [request setValue: refreshToken forHTTPHeaderField: @ "refresh-token"]; 61 62 // network method 63 AFHTTPRequestOperation * httpRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest: request]; 64 [httpRequestOperation condition: ^ (AFHTTPRequestOperation * operation, id responseObject) {65 refresh (operation); 66} failure: ^ (AFHTTPRequestOperation * operation, NSError * error) {67 refresh (operation ); 68}]; 69 [httpRequestOperation start]; 70} 71 @ end