I. A brief overview
OAuth2.0 is the next version of the OAuth protocol and is often used for mobile client development, which is a more secure mechanism. In OAuth 2.0, server will issue a short-term access token and a long-life refresh token. This allows the client to obtain a new access token without the user being re-operating, and also limits the validity period of access tokens. That is, when the access token sent by sever expires, the client calls the method, sends access token and refresh token to the server, and the server returns the new access token and refresh token.
Second, the application scenario
After the user logs in, the server releases an access token for a valid time, and a long lifetime refresh token is issued. When users make other network requests, they add access tokens to the request body (no need to add a refresh token). If access token expires during the request, the corresponding status code is returned. The callback then uses a callback method to send the original access token and refresh token to the server in the callback method body for the new access token and refresh token. Then add the new access token to the request body and reload the network request.
Limit the effective time for access tokens, just to improve security. The user is unaware that access token has expired and re-fetched and reloaded the request. This mechanism is especially common in clients such as QQ and Weibo.
Third, instance code
(1) This class inherits the Afhttpsessionmanager class in afnetworking and overrides the method inside.
NetWorkCallBack.h:
1 #import <Foundation/Foundation.h>2#import <AFNetworking.h>3@ Interface Networkcallback:afhttpsessionmanager45@end
NETWORKCALLBACK.M:
1 #import "NetWorkCallBack.h"2 #import<SSKeychain.h>3 @implementationNetworkcallback4 5-(Nsurlsessiondatatask *) Datataskwithrequest: (Nsmutableurlrequest *) urlrequest Completionhandler: (void(^) (Nsurlresponse *response,IDResponseobject, Nserror *error)) originalcompletionhandler{6 7 //Create a completion block that wraps the original8 void(^authfailblock) (Nsurlresponse *response,IDResponseobject, nserror *error) = ^ (Nsurlresponse *response,IDResponseobject, Nserror *error)9 {Tennshttpurlresponse* HttpResponse = (nshttpurlresponse*) response; One if([httpresponse statusCode] = =401){ A - //if access token expires, return an error, call this block -Dispatch_async (Dispatch_get_global_queue (Dispatch_queue_priority_low,0), ^{ the - //call the Refreshaccesstoken method to refresh access token. -[Self refreshaccesstoken:^ (afhttprequestoperation *operation) { - //Accessing the new access token, where I used the keychain access +Nsdictionary *headerinfo =Operation.response.allHeaderFields; -NSString *newaccesstoken = [HeaderInfo objectforkey:@"Access-token"]; +NSString *newrefreshtoken = [HeaderInfo objectforkey:@"Refresh-token"]; A[Sskeychain Deletepasswordforservice:@"<key>"Account@"Access-token"]; at[Sskeychain Deletepasswordforservice:@"<key>"Account@"Refresh-token"]; -[Sskeychain Setpassword:newaccesstoken Forservice:@"<key>"Account@"Access-token"]; -[Sskeychain Setpassword:newrefreshtoken Forservice:@"<key>"Account@"Refresh-token"]; - - //Add the new access token to the original request body and resend the request. -[URLRequest Setvalue:newaccesstoken Forhttpheaderfield:@"Access-token"]; in -Nsurlsessiondatatask *originaltask =[Super Datataskwithrequest:urlrequest Completionhandler:originalcompletionhandler]; to [Originaltask resume]; + }]; - }); the}Else{ *NSLog (@"No auth error"); $ Originalcompletionhandler (response, Responseobject, error);Panax Notoginseng } - }; the +Nsurlsessiondatatask *stask =[Super Datataskwithrequest:urlrequest Completionhandler:authfailblock]; A the returnStask; + - }; $ $ - /* - * Method of obtaining new tokens. How to get customizable, I use the afnetworking afhttprequestoperation class here the */ --(void) Refreshaccesstoken: (void(^) (Afhttprequestoperation *responseobject)) refresh{WuyiNsmutableurlrequest *request = [[Nsmutableurlrequest alloc] Initwithurl:@"<yourURL>"]; the -[Request SetValue:@"Application/json"Forhttpheaderfield:@"Content-type"]; Wu - //Send the original access token and refresh token to the server for a new token AboutNSString *accesstoken = [Sskeychain passwordforservice:@"<key>"Account@"Access-token"]; $NSString *refreshtoken = [Sskeychain passwordforservice:@"<key>"Account@"Refresh-token"]; - -[Request Setvalue:accesstoken Forhttpheaderfield:@"Access-token"]; -[Request Setvalue:refreshtoken Forhttpheaderfield:@"Refresh-token"]; A + //Execute Network Method theAfhttprequestoperation *httprequestoperation =[[Afhttprequestoperation alloc] initwithrequest:request]; -[Httprequestoperation setcompletionblockwithsuccess:^ (afhttprequestoperation * operation,IDresponseobject) { $ Refresh (operation); the} failure:^ (Afhttprequestoperation * operation, Nserror *error) { the Refresh (operation); the }]; the [httprequestoperation start]; - } in @end
iOS implementation OAuth2.0 Refresh access token and request data operation again