Apple Sign In Web implementation. Not getting User Info - oauth

We are implementing the Sign In with Apple functionality for web application. We are following the ReST based approach. The authorization call is working fine and we are getting the 'code' and 'state' values on the return request object. But I am not getting the customer info.
Authorization end point : https://appleid.apple.com/auth/authorize
The user info section is completely missing on the apple doc. Is anyone know which endpoint to hit for getting the user info and what is the request format.
I have tried the token API call from Apple and I'm getting the response as 'unsupported_grant_type'
Endpoint : appleid.apple.com/auth/token
Header : svc.addHeader("Content-Type", "application/x-www-form-urlencoded");
Body :
{'client_id' : client_id, 'client_secret_key' : client_secret_key,
'grant_type' : grant_type, 'code' : code, 'redirect_uri' : redirect_uri}
grand_type value we set as 'authorization_code'.
Response service=AppleSignInTokenService status=ERROR errorCode=400 errorMessage={"error":"unsupported_grant_type"}
Please let me know where I'm going wrong.

If you getting 400 error, check the redirect URL exist at Service ID redirect section or not. Make sure the client id is the same as the Service ID Identifier or not.
If you getting 200, but no user information returns. That could be you already do sign in with apple with your site, you could go to https://appleid.apple.com/account/manage, then click APPS & WEBSITES USING APPLE ID under security. If you see your site then click stop using Apple ID. Now, when you back to the site to do sign in again, the user information will be included. Seems like apple only returns user information on first time.

Related

Account linking with actions on google

I am facing an issue regarding account linking in Actions on Google:
I am able to authenticate the user and access his email address and username however after this how can I redirect the user back to the google assistant and close the browser where he was authenticated?
Any help will be appreciated!
Update: Hey Prisoner thanks a lot for that.
I did what you said and yeah now it does redirect to google.com but without result_code=SUCCESS when I test it in the simulator.
The link is:
https://www.google.co.in/?gws_rd=cr&dcr=0&ei=z77fWbjQGIXxvATs_oqwBA
Now if I type talk to... again it shows me the message you need to link your account!
In the device the browser automatically closes and it shows SIGNING_IN however when I type an intent it is not recognized.
It would be great if you could point me in the right direction! (I am not sure but I might be at the token exchange stage that you mentioned, but I don't have a clue how to proceed!)
Update 2: As requested the entire flow that I am following:
This is the URL that I receive from debugInfo:
https://assistant.google.com/services/auth/handoffs/auth/start?account_name=cha***#gmail.com&provider=***_dev&scopes=email&return_url=https://www.google.com/
When I paste this in the browser the request that I receive at the authorization endpoint is:
ImmutableMultiDict([
('response_type', 'code'),
('client_id', ****.apps.googleusercontent.com'),
('redirect_uri', 'https://oauth-redirect.googleusercontent.com/r/****'),
('scope', 'email'),
('state', ' CtcCQUxWM2ROU3hNMjl4LUItVXhQSGd4THRMLU4yNExnb3lYbGRKQnQwa3NwTVFva19NUWpYNE5jNGJURzIyZFN3RDBXd2d4enFGVWJGb0Q0ZW1vaS1OaFdkaHdhb05HZ2xlWTR6SllKVlRWYktwd09faklyUTVheFhQbGw2dmVKYzVFTk05N3B1QkxaZG41RVdHN0wyTktvRFdCYzFPVFBzM1dQUlFtN2RmM1VtRU4****(state)')
])
The response (redirect_url) that I send back:
https://accounts.google.com/o/oauth2/v2/auth?scope=email&response_type=code&redirect_uri=https%3A%2F%2F******.herokuapp.com%2Fcallback%2Fgoogle&client_id=****.apps.googleusercontent.com
When it reaches my endpoint again the request arguments are:
ImmutableMultiDict([
('code', '4/***********')
])
Now I am able to access the email address and other details
The url that I redirect to from here:
https://oauth-redirect.googleusercontent.com/r/****?code=abcdefgh&state=CtcCQUxWM2ROU3hNMjl4LUItVXhQSGd4THRMLU4yNExnb3lYbGRKQnQwa3NwTVFva19NUWpYNE5jNGJURzIyZFN3RDBXd2d4enFGVWJGb0Q0ZW1vaS1OaFdkaHdhb05HZ2xlWTR6SllKVlRWYktwd09faklyUTVheFhQbGw2dmVKYzVFTk05N3B1QkxaZG41RVdHN0wyTktvRFdCYzFPVFBzM1dQUlFtN2RmM1VtRU4****(state)
This redirects me to :
https://www.google.co.in/?gws_rd=cr&dcr=0&ei=5c_fWdfKNYndvASO7o6ACA
Edit 3: I checked the network logs:
result_code=FAILURE&result_message=Account+linking+failed
I also added /token/google as the token URL in AoG. It is detected in heroku however I never receive this request in my code.
Note: I am using python flask and hosting my app on heroku
Once you have authenticated the user, you'll need to return a temporary auth code back to Google. Later, Google will exchange this auth code for an access token and a refresh token, but you're not there yet. The important part is that this code needs to be unique and that, later, you'll be able to recognize what user it is for. The code should be valid for a limited time - 10 minutes is a generally accepted time frame.
In the request Google sent to you as part of the login, they've provided a redirect_uri and a state as parameters. You'll need to use these in your reply. (state can be anything - you shouldn't care what it is, you're just going to send it back with your redirect. Its purpose is to improve security by preventing replay attacks.)
Verify that the redirect_uri has the form
https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID
Where YOUR_PROJECT_ID is... you guessed it, the ID of your project. You can find this in the cloud console.
You'll then redirect the user to this URL with a few additional parameters:
https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID?code=AUTHORIZATION_CODE&state=STATE_STRING
Where YOUR_PROJECT_ID is as noted above, AUTHORIZATION_CODE is the code you've generated, and STATE_STRING is the value of the state parameter that you were sent in the request.
For details, you can see https://developers.google.com/actions/identity/oauth2-code-flow#handle_user_sign-in

Instagram oauth api gives { "code": 400, "error_type": "OAuthException", "error_message": "No matching code found." }

I am working on an application that integrates with Instagram API to access the user information. I successfully fetch the Access Token using the authorize url but unable to fetch the userId using access_token url:
i am tried both the endpoints:
https://api.instagram.com/oauth/access_token?client_id=48275564e2c445f6b8e1356djfha3e0c&client_secret=ab2062da9f314e3489dke7ae9cbe6e5d&redirect_uri=http://localhost&grant_type=authorization_code
https://api.instagram.com/oauth/access_token
with the post body as:
client_id=48275564e2c445f6b8e1356djfha3e0c&client_secret=ab2062da9f314e3489dke7ae9cbe6e5d&redirect_uri=http://localhost&grant_type=authorization_code&code=1351860224.4827556.5dc92c4d15ea4a4ea1b0d33eaf0eef19
(The data in the request is modified), But i am getting the follwing
{
"code": 400,
"error_type": "OAuthException",
"error_message": "No matching code found."
}
I have seen tons of queries and questions but could not find any solution to the problem.
The couple of questions i have is:
1) is the field code in the URL is same as access_token, if not how could i get the code field's value.
2) is there any other mechanism(API) to fetch the user details given the username is not known.
Please help me as i am completely stuck and running out my deadlines.
For me unchecking Disable implicit OAuth in instagram developer -> manage clients fixed the issue
I found that using either form-data or application/x-www-form-urlencoded works fine. The most important is the code you get from redirect uri is only used by one request. It means you could request the access token once for the code. If the you request more than one time with same code, you'll get the error like this:
{
code: 400,
error_type: "OAuthException",
error_message: "Matching code was not found or was already used."
}
Wish you all the best ;)
Try to urlEncode the redirect_uri param to
http%3A%2F%2Flocalhost
And your code param contains the "." character which might be a error.
code=1351860224.4827556.5dc92c4d15ea4a4ea1b0d33eaf0eef19
might caused the problem
"error_message": "No matching code found."
"5dc92c4d15ea4a4ea1b0d33eaf0eef19" seems to be the correct code
I got same error. It seems that instagram's spam system disable user's access to any non-official application. Just change user's password. In my case it was help.
Also try create another application.
UPD
From my answer to another question
It looks like users get more than one code, and you see first code, but need second. Try relogin users, if you gets error. User will not see instagram page with confirm button, just redirections.
Possible algorithm of error:
1. User click auth link.
2. Get first code.
3. User click auth link (twice, redirection problem, public auth system, etc.)
4. Get another code (even on the same client_id, redirect_uri).
5. You get first code.
6. But first code already doesn't exists.
The problem is here that need redirect url set as http://localhost/signin-instagram
signin-instagram part is very important
So go to Instagram.com/developer ->Manage Client-> Security -> Valid redirect URIs set with that end http:/../signin-instagram
Off late instagram python snippet fails due to missing content-type HTTP header
response, content = http_object.request(url, method="POST", body=data,headers = {"Content-type": "application/x-www-form-urlencoded"})
adding application/x-www-form-urlencoded worked for me
I will mention what worked for me.
Step 1. Generate a new client secret from you panel.
Step 2. Follow the step 1 mentioned here to obtain the code again.
Step 3. Send the request again with the changed parameters.
Make sure you are logged in the browser when you send the request. You will get the required response.
Go into Facebook for Developers > Your app. Click on "Roles" and add an Instagram test-account under "Instagram Testers".
Log into instagram.com and go to: Settings > Security > Apps and Websites, where you will accept the test invitation.
Prepare your URL link, which you will paste into the web browser. Make sure to use a valid redirect URI from "Valid OAuth Redirect URIs" from the Instagram Basic Display settings.
If you did everything right, the Instagram tester account for the app, will have the option to gain access to user_profile,user_media. Continue the process to get the code which you can exchange for a short-lived access token.

How to use Stripe Connect in an iOS app

Has anyone had success using Stripe connect with an iOS app. I have a few questions:
I'm following the guidelines here: https://stripe.com/docs/connect/getting-started
Registering an Application: easy, no problem here
Then a little further down:
Send your users to Stripe: again, easy no problem here, I just have a button that opens up the link in a UIWebView. I assume having the client_id in the URL is fine? A lot of my uncertainty is what IDs/keys I should hard-code into the app
Then a little further down:
After the user connects or creates a Stripe account, we'll redirect them back to the redirect_uri you set in yourapplication settings with a code parameter or an error.
What I'm doing here is using the UIWebview's webView:shouldStartLoadWithReqest:navigationType delegate method to check for the string "code=" in the URL. If it finds that, then I'm able to grab the "code" parameter. So in reality, the redirect_uri is completely unnecessary for me. Is this the right way to handle this? Should I be doing this within my app or on my server?
After receiving the code, we are supposed to make a POST call to receive an access_token. Again, should this be done within the app or on the Server? It requires the use of a secret_key, so I'm guessing server? And how do I send credit card information along with this token if the token needs to be sent to the server? I know how to obtain the card number, exp date, and CVV. But in terms of passing it to the server (with or without the token) is something I'm not sure of.
Then when it comes to actually writing PHP, Ruby, or Python code on the server, I'm at a total loss.
Any help would be greatly appreciated.
You should setup a small web app to create stripe charges and storing you customers Authorization Code. Configure two routes in your web app for redirect_uri and webhook_uri and add the url in your Stripe Apps settings. The charges should be created from a server side app because it requires the secret_key / authorization_code which should not be stored in an iPad app. Otherwise they may lead to a security leak. I'm trying to describe the concept below:
Provide the stripe connect button in your app and set the link to open in Safari (not in an web view). You should add a state parameter to the url with an id which is unique to your users.
On tapping the button your user will be redirected to Stripe where s/he will be asked to authorize your application. Upon authorization stripe will hit your redirect_uri with a authorization_code and the state you previously provided. Do a post call according to Stripe Documentation with the authorization_code to get an access_token. Store the access_token mapped with the state in a database.
Define a custom url scheme in your app. Invoke the custom url from your web app. The user supposed to open the url in mobile safari. So invoking the custom url will reopen your application. You can pass an additional parameter to indicate failure / success. In your app update the view based on this parameter.
Now you are all set to create a charge on your server on behalf of the iPad user. Use stripe iOS sdk to generate a card_token from the card information. It'll require your stripe publishable_key. Then define an api in your web app which takes 3 parameters: card_token, user_id and amount. Call this api from your iPad app whenever you want to create a charge. You can also encrypt this information with a key if you're worried about security using any standard encryption method. You can easily decrypt the info in your web app as you know the key.
When this api is called from the iPad app you'll receive the user_id (which you saved as state previously), card_token and amount. Retrieve the access_token mapped to the user_id (or state). You can then made a charge on behalf of the user using the access_token, card_token and amount.
You can use ruby / php / python / node in the server as Stripe provides sdk for them. I assume other languages can be used as well as there is a REST interface.
Please note that this is just a concept. It should work like it but I haven't implemented it yet. I'll update this answer with sample code when I'm done.
You can use UIWebView. You will still need to use redirect urls and monitor the redirect using the delegate "webView:shouldStartLoadWithRequest:navigationType:"

.NET - Update status (tweet) to Twitter without PIN or real Callback url?

I'm trying to write an app that can tweet using an 'application' I registered with Twitter. I am using TweetSharp and have tried to get my TwitterService set up as follows:
public Twitter(string consumerKey, string consumerSecret)
{
this.twitterService = new TwitterService(consumerKey, consumerSecret);
OAuthRequestToken oAuthRequestToken = this.twitterService.GetRequestToken();
Uri uri = this.twitterService.GetAuthorizationUri(oAuthRequestToken);
Process.Start(uri.ToString());
OAuthAccessToken oAuthAccessToken =
this.twitterService.GetAccessToken(oAuthRequestToken);
this.twitterService
.AuthenticateWith(oAuthAccessToken.Token, oAuthAccessToken.TokenSecret);
}
It gets to the OAuthAccessToken line and then takes me to the Authorize [my app] to use your account? page on the Twitter website. Before I specified a phony callback url, it displayed a page with the PIN that my user is supposed to enter when I clicked the 'Authorize app' button. Then when I added a phony callback url, it would attempt to go to that page and my code would blow to smithereens with the following error:
The remote server returned an error: (401) Unauthorized.
What I want to know is: can I tweet programatically without the need to enter a PIN or have a legitimate callback url?
Tweets must be sent in the context of a user. (Ref: POST statuses/update.) Therefore, your app must get the user's authorization (an OAuth access token) in order to send a Tweet. Since you can't get an access token without using either PIN-based authentication or a callback URL, I'm afraid that what you are asking simply cannot be done.
If, however, you just want to avoid prompting your users to enter the PIN each time they start your app, then the answer is simple: Once you have a valid access token, save it somewhere (e.g. to a file) and then reload it next time your app runs. For my WinForms app, I use .NET's built-in per-user Settings mechanism to store the Access Token and Access Token Secret. A web app would probably be better off using a database or similar to persist access tokens.
Note: If you do this, you'll also need to check the validity of the stored access token, and repeat the authorization process if it's no longer valid. The Twitter API documentation suggests using the GET account/verify_credentials method for this purpose.

iOS facebook SDK 3 > Get the signed request

I try to get the signed request to login the user via a webservice but I only have access to the accessToken on FBSession.
I saw this link
Facebook Signed Request for iOS (HMAC SHA256)
who shows how to convert the signed_request but doesn't show how to get it.
Need help :)
If I undersand you right you want your app to login and then make a call to a server where you need to check the users credential again.
I used this tutorial for the authentication.
Then when I call the server I send the accessToken property as a parameter to check the users credentials on the server. You can get the token value like this:
FBSession.activeSession.accessToken
On the server side you can then set the access token to the value you got from the app.
I compiled a gist that generates a signed request which you can then use to authenticate a user on your server without having to query the graph API.
You can find it here: https://gist.github.com/3962188
You can find the original question I compiled it for here: Facebook iOS SDK to return a signed request object upon login
Please note that most of the code is simply a compilation of existing open source code, but I haven't seen any fully working implementation like this anywhere.

Resources