I have a REST API that allows client to login with LinkedIn passing an access token from LinkedIn.
I have created this service by getting the access token from the Javascript API and sending to log in, than the API calls LinkedIn API to retrieve the user data. This works fine, but we are having trouble with the iOS generated access token.
We are using LinkedIn OAuth Sample Client to log in into LinkedIn on mobile and than we get the access token. With that access token, our API cannot call LinkedIn.
My question is: is this the right way to use LinkedIn API inside an API? And, if it is, how can I generate the correct access token in iOS integration to my API can use that?
You need to follow simple steps.
1. You need to request LinkedIn for authorisation of user. (an authorisation code
will be received here in response.)
2. Using the authorisation code you need to make a POST request to linkedIn with the authorisation code
received above.
In ViewDidLoad
-(void)viewDidLoad
{
#warning:- Please provide your clientID and clientSecret
linkedInKey = @"YOUR_CLIENT_ID_HERE";
linkedInSecret = @"YOUR_CLIENT_SECRET_HERE";
authorizationEndPoint = @"https://www.linkedin.com/uas/oauth2/authorization";
accessTokenEndPoint = @"https://www.linkedin.com/uas/oauth2/accessToken";
#warning:- Please provide your redirectUrl here.
NSString *redirectURL = @"http://REDIRECT_URL_THAT_YOU_HAVE_PROVIDED_WHILE_REGISTERING_YOUR_APP";
encodedRdirectURL = [redirectURL stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.alphanumericCharacterSet];
_webView.delegate = self;
[self startAuthorisation];
}
-(void)startAuthorisation
{
// Specify the response type which should always be "code".
NSString *responseType = @"code";
// Create a random string
NSString *state = @"anyRandomString";
// Set preferred scope. It depends on your preference.
NSString *scope = @"w_share";
// Create the authorization URL string.
NSString *authorizationURL = [NSString stringWithFormat:@"%@?response_type=%@&client_id=%@&redirect_uri=%@&state=%@&scope=%@",authorizationEndPoint,responseType,linkedInKey,encodedRdirectURL,state,scope];
NSLog(@"%@",authorizationURL);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:authorizationURL]];
[_webView loadRequest:request];
}
#pragma mark- WebView Delegate.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *url = request.URL;
//here we will catch the response of the server which will redirect to our redirect url. Hence we first check for the host(which is our redirect url) then only extract the code.
#warning:- Please provide your redirectUrl here.
if ([url.host isEqualToString:@"www.Your_redirect_url.com"])
{
if ([url.absoluteString rangeOfString:@"code"].length)
{
//response containing the authorisation code looks somehow like below.
//http://www.Your_redirect_url.com?<strong>code=AQSetQ252oOM237XeXvUreC1tgnjR-VC1djehRxEUbyZ-sS11vYe0r0JyRbe9PGois7Xf42g91cnUOE5mAEKU1jpjogEUNynRswyjg2I3JG_pffOClk</strong>&state=linkedin1450703646
//......obtaining the code from the response......//
NSArray *urlParts = [url.absoluteString componentsSeparatedByString:@"?"];
NSString *codePart = [urlParts objectAtIndex:1];
NSArray *codeParts = [codePart componentsSeparatedByString:@"="];
NSString *code = [codeParts objectAtIndex:1];
[self requestforAccessToken:code];
}
}
return YES;
}
- (void)requestforAccessToken:(NSString *)authorisationCode
{
NSString *grantType = @"authorization_code";
NSString *postParameter = [NSString stringWithFormat:@"grant_type=%@&code=%@&redirect_uri=%@&client_id=%@&client_secret=%@",grantType,authorisationCode,encodedRdirectURL,linkedInKey,linkedInSecret];
NSData *postdata = [postParameter dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:accessTokenEndPoint]];
request.HTTPMethod = @"POST";
request.HTTPBody = postdata;
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
manager.responseSerializer = [AFJSONResponseSerializer
serializerWithReadingOptions:NSJSONReadingAllowFragments];
[[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * response, id responseObject, NSError * error )
{
if (!error)
{
NSLog(@"Reply JSON: %@", responseObject);
NSString *accessToken = [responseObject objectForKey:@"access_token"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:accessToken forKey:@"linkedInAccessToken"];
[defaults synchronize];
}
}] resume];
}
I have used AFNetworking library here. So please get the library from gitHub and add it to your project. You need to import AFHTTPSessionManager.h
in your viewController for this purpose.
#warning:- please declare these following strings as global variable under interface as.
@interface WebViewController ()<UIWebViewDelegate>
{
NSString *linkedInKey;
NSString *linkedInSecret;
NSString *authorizationEndPoint;
NSString *accessTokenEndPoint;
NSString *encodedRdirectURL;
}
And also I have taken a UIWebView
and connected to it with the IBOutlet
with the name webView
, you can find this in the above code.
Don't forget to confirm the UIWebViewDelegate.
Hope this will help.
Good Luck.