Gmail API autologin in swift - ios

I'm using this example
Gmail Api
I tried to find a proper method of the api to do this and it has not been possible.
It occurred to me to save credentials in NSUserDefaults and add them to service.authorizer manually.
This works, but in about an hour I answered: The operation Could not be completed. (Invalid Credentials).
I wonder if there is a function to refresh these credentials.

Finally i find the solution.
I'm mantain the NSUserDefault Functionality
curl -d "client_id=yourClientId&client_secret=yourClientSecret&refresh_token=yourRefreshToken&grant_type=refresh_token" https://www.googleapis.com/oauth2/v3/token
The Response is something like this:
{
"access_token": "ya29.KALxxxxyvE5PI3-s6oBAP74uGFE8rOhho5XYfvExfU3lxHdX23HWbKlkR4YI1xxxx",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "xjc4ZDg3NWY5MDA5YzMzZjFlODljOGExMDFjM2UwNDMyNWQ2YmQ0MTEifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXRfaGFzaCI6InRJWVE0b2pBZfNyRlJXdFEiLCJhdWQiOiIyMDM3MjIwMDA2NzMtdGIwamF1OWhwamFsa21yaHFxcDkybnBxamo2ZjhkcWcuYXBwcy5nb29nbGV1c2VyY29udGVx1ODM5MTE5MDk0OTAzMjg3NjAiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiMjAzNzIyMDAwNjczLXRiMGphdTlocGphbGttcmhxcXA5Mm5wcWpqNmY4ZHFnLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiaGQiOiJ2b3ZdwiZW1haWwiOiJqZ29uemFsZXpAdm92c29sdXRpb25zLmNvbSIsImlhdCI6MTQ0NzE2OTU5NSwiZXhwIjoxNDQ3MTczMTk1fQ.gZiYdgEPhYkQTvjgxugaMaXTIH3652_E_3h_khHgaKFA56ko3VqBF9qlzJ-1LDIoTO8G2eQWa6ncE7aEwLvxelZ8429iJUCIH-1cmeuck_LWpFIdQ9sQN8u4I7ABTRWPpZ3vL8nXMNmPGynvCDWimffYCGWeVZGs3uv0O7pFftqIKMJchVk_WyC5fm9i8m-cGPN-UcrvgZKrFEOMydvF83HQzIR-x28nB1evbMV6WN8guBdZ6pVAr_2agyzoNuSO5tkV_O-790IRmU432Omv2nHBD3QQKEqv6aHe3i_F3ioPREuWduYY3yjlg0QYyh-nrzAXyzF3wbg"
}
i replace the access_token saved in userDefault with access_token from response.
Replace Values in GTLServiceGmail service.authorizer
More information here

Related

Unable to use OAuth token to connect to Snowflake from Databricks "EXTERNAL_OAUTH_USER_CLAIM_MISSING"

I am trying to use an OAuth token to connect to Snowflake from Databricks.
I have configured using the official documentation (https://docs.snowflake.com/en/user-guide/oauth-azure.html#step-3-collect-azure-ad-information-for-snowflake).
When request the token I also retrieve what appears to be a valid token. The json in the format {'token_type': 'Bearer', 'expires_in': 3599, 'ext_expires_in': 3599, 'access_token': 'token here}'
However, when I try to use this token it comes as invalid - checking in Snowflake the result is the following:
Using https://jwt.ms/ to look at the claims in my token I find the following: aud, iss, iat, nbf, exp, aio, appid, appidacr, idp, oid, rh, roles, sub, tid, uti, ver.
Which claims are missing?
Most likely the issue issue is that the claim parameter set for OAuth integration object on Snowflake is not passing the right value. Review the following article which details the steps:
https://community.snowflake.com/s/article/Create-Security-Integration-User-To-Use-With-OAuth-Client-Token-With-Azure-AD

Decode Access Token getting from frontend IOS application to fetch user information using Okta and Node JS

I am trying to decode the access token at the backend which i receive from frontend using okta jwt verifier. I am not sure about which type of token i am getting as it does not seems to be JWT token.Login module has developed by some other company and client is not aware about the Encoded mechanism.So the access token we are getting is of the form:
The entire response that i am receiving at login -
success({
"scope": "userinfo offline_access",
"token_type": "Bearer",
"expires_in": 3600,
"access_token": "CfDJ8G7oFS712aJJkUnWhDsiXlVRL4XtxRzsNbl6up_LvGbZlZtW1RwE9pRxsVC73MT6I-r7Wvj7rVsb-jp6hghJYrHLrk9KqEmUDOtHDhE63edAGnPm3WntjEL_dQyanOXHb7aiSWFeLDVak_tV0lH6DSMCbpvy-6Cr5TPmCBHRUZybOQWYl36aidrskEvZACuPy3AvfkSCnIcFIjDuh7JSk7IU_LPZzI42Pa-O2-6V4LGf6pqtdLmO1KZIPD6gtOJn7Fidk_SDOxW74OuPakBLCf_7kQAwV1qB8lyG_Dcz_fL5qK45T9iqtyf_nB6rtwvdj07rzqgGGQ6T_JAUOAo745xoF7gnl-hIZ8pxu9OPgGdC8ymFqSneFuOhv2QZty6OMVc_ORlqoW3XTtntmBuEBSYUKnYmb4n-JAkg_cAvj-lvugxBrlHJqFKUabPbZC6_MWsMabonq0IAI_-CP7OcFcjRXGgyqgTtyYYU8UfbsYhJtp7eYyQSd_WNebiEuYOQoqrCigY7XzHoCV97YQ1TuotpuLFtHDzXc1gi_1DAozrira2LCh2DOrbAsmucKwun-G5pi2VbjFwTLknbz9vcfgrfxhq6AD9P1SALG2UtPgBMoMJ0ZW4VyEJ83NCAqaOrhHMuNrPEwdB3vrEqydJerH0xbL3Z8NtE54qu_vN6IGt8yO1SkQFNibui3FBG8Aq26zsjMusC9AlXX1EMqyLK5w9VzdbzEbeY7T5od9gYqMUR_5N1Xpr8vNKuMAanqNBHqkHBsOTgumSluSoa4BKHPS4eSvImo8ip2siKRkk3c348XqR_kIGToyuElROpVZuZ1PfTTp0tYpneCfKIHwtymt11gq-vZ-3dPjOSGQU-W5zemFAyhrEv-6NSQfGI-vi4rsWPr6fpeGgiEA3CkBUanbrXbsM3-48cHFkj0NkG3z1bTGqoAHmwP9Fub8-EhQDpNd74znYyi75Un_OjbLb2pvZ8Vp6ewRClaCEjXL44_7SOWyQ-uNnjIS_wlJ01WzRj6Nj9VNTlhYktBhi0LbUIYiaRrazCF671pc3KxYmLQzh8tLw-x-pG5UHLQNnId6YgbNL9vXi8B7NaKOMMI7ip46mO32rSxS4TE2cWjxUFeDMoRxN3XaZ9TLANvrvDpdZVSRyTpqHVmjk5Lfnj8GAUG4FY9NWYHsGLwXnT3Nn2GAgKjjVRTpUoSuXrqDCzM0fXDRAFPZ8SLe5YviG6_O4AtqGGzqj7wUUcotkwrH4WU7xVcDBip4L8yEudNCPpQkLOs0tdU5qysO8pAyVgJ89taBWeCB3VkKTdi9VXgOpUjg_wJU2eAez_xVkf3qgovk80vivhIrjRVAh0vyPVmYWwF1uwsjzx_w3_3HYspbPIC7KSpmxaMdiTg6a2wJtimdo_wmhNIJhe-EY60VG0Hlnmv6kuiakXqhyuFLl-XC97TrZL",
"refresh_token": "CfDJ8G7oFS712aJJkUnWhDsiXlUEOo0WAwIjVHVFeMiNBX4jl9mIJhwKW2uzS4OaiwhddF9LBbKOWkGaKw8vNynImRV0wJmHpp8U6iWP3UIY29s6rD65_iwrsPYfiBnrGUfusTCPRLG43Px1VQIgsBGhSGkys8t89IlKFLn7ec48Hkj8SKE0gAU6MhncTCZcyuuPzy-ip_u7OSwfxVd495qcpsnTbcxU2kfITyoVOl25NBXKYdaemMoqznEN4DMgfXNStNNTXgl0P6W6ag7frCVaiQSd9vHS9wohmLVmGH6-jyZ7Fad7LRIKMZgtMCONssGE2b8Bi0FhCJsKwYelFRcfR2Ox4IRBz0yTe8bQ3qfgYxcO4DzP9IT6kg0gZODNIi-CfhtOufMGUS5ZW6jTKXz5JFjF7JpwlY3vZokIWtu-HWrLsrFYUBGvBFxE6vWMuJ9GKv1B8Av85BKilWe3t8ND24-zDj0LIl7eZGmVa596VhoB7uepL4rQQb22f4Qagcw3NwUUfwl9Y4F-nguYZZxFNeESJItJ5Zlk6QUMaOQytMqCbxIB1ZuO_9-1qpo4EFv5rvFUPyMsU6o0Z78jytUVipgWu91Uzy0EDa6Qq9HgmYKykocxpMgerfKWo4W1z1qiCdjQ5g5n-Vzv50ZfD18HiCk1F3viiUEvMFUE3JmXVJ_YVoO0170LFryhSpTCsgx-UxiePKRXmhTheeOGxMNbhYCI6TXhgknesYFibdbds-3oLe135B0RJ3wG3_-NuEVLARWsPabYwF8puHIpHMH6io0oC4TcerOL-HfyI0CfvxNMRHydGQhVwSk72ja7yi0I_1BnnKop2UMtt_xGfkUkUlNXfJkvXAigUC77IphlfnMoQ5WZMWj-sPyHR-180z4OkeS8vXAwGxDFYI2Cl0Dc1XQXsbxQq98zxFWh7oni4EUxeb5eLoiK_zTcmQsq-4uq_W-PRGRS-QlkiHWKMvNykMWhYBSxpzHORfG4RRE4fVbdWbHMU0gh2d74mbXCJanw-ViYXdO2u3zh-k8oMbmHp2nNw3SBsMcCZPE2pOkdNlxGJTF1B9pS9BfTlxc60uF7JC9u57UqjGa-bA_xVOnvdB72JtVjtpV4eU9OWczfkCNlnWt7q4QBskVpI7zMuQfFhWaa4lbilrKuUwl1O057qvcP2cm800qeT3FGgebIXnfFmUEXCA4K28nvPa50yHXxK8nS6iKsPZSKSXaDenyCLjejxd4IyrYj0B02GXJLq7SmpZVYaQRoUq8AAawI0OUxoD31jj_bR_IdComt1Fljiz0y8BZxH74_sYl0gNTV1o6tDOEbE_2BeX7fiTJtMOk33W5kqeqsHA9stPUk8rZyOLSoK3u1tLAr0wZfnWSMw6GXu1gtG8UKuYD5SkqtnjPSOKZkvgS2D_aLKaBdNPqwoWSlqsLETiu2XbnDrunaSpRyIddYnHG9_r9zfSzXHYVEIjkJc9ix_V3tFjDOHkhi6Jg1qtYyG3l-BWGODo0uyduYKDoVJ9hjHdAlFy7gp87iE_LW-LN56IcziAFfPyV5cqYyQ571UFFET4kVTK3ypRrkEgPwwaGvj8Mm0IptJDpXOD6_wJm92YGgwlkGFsly1girz9YcOZpXfzo7KU1-s_zxSPLSx15eRvKU8FRblcSZZI1oGR8x3h1Cw-3dS3PkPkeidTVwN9In_VDWx4RgR6uwt6yxQJ49ZMKufvnv2DaZVr2pzSuj9a4BtNw7c_sIohE-Or8GbaksncXfD_JGMXR28NsDGLaH-uLJGPdGDK0YzO3bdkqAg4RQo1QHDCLY6X11pY3jIVhsvtLZzwrR3K81-Ff_QwDPBV0D8RrMVnAKYvb4AOdBDXWrrO2BckrvAFqfA1R-BFTJUAOJC9KH18qN"
},
Optional([
AnyHashable("Pragma"): no-cache,
AnyHashable("x-amzn-remapped-connection"): keep-alive,
AnyHashable("x-cache"): Missfromcloudfront,
AnyHashable("x-amzn-remapped-content-length"): 3516,
AnyHashable("Content-Type"): application/json;charset=UTF-8,
AnyHashable("Date"): Mon,
AnyHashable("x-amz-cf-id"): o2aYOoNsMY
3jqyQfcvtCsj8qitdXuHP63Jm8A1Hg1Edo-bvJxIxq9w==,
AnyHashable("x-flg-call-id"): 88aa3619167546ca8ed0304402502fq2,
AnyHashable("x-amz-cf-pop"): BOM51-C1,
AnyHashable("x-amzn-remapped-date"): Mon, 03Feb202008: 03: 44GMT,
AnyHashable("Content-Length"): 3516,
AnyHashable("Expires"): Thu,01Jan197000: 00: 00GMT,
AnyHashable("Set-Cookie"): .AspNetCore.Identity.Application=;expires=Thu,
01Jan197000: 00: 00GMT;
path=/;samesite=lax,Identity.External=;expires=Thu,
01Jan197000: 00: 00GMT;path=/;samesite=lax,
Identity.TwoFactorUserId=;expires=Thu,
01Jan197000: 00: 00GMT;path=/;samesite=lax,
AnyHashable("x-amzn-remapped-server"): Kestrel,
AnyHashable("x-amz-apigw-id"): ,
AnyHashable("Via"): ,
AnyHashable("x-amzn-requestid"): 5c6e9360-7245-42d3-aa0c-56a6a73d286f,
AnyHashable("Cache-Control"): no-cache
]))
I am unable to find out what type of access token is it. Client has only told us that they have used Okta to encrypt the login credentials and we are unable to find out from frontend ios that what kind of mechanism have they used to encrypt the user credentials.
It does not have separated period(".") just like JWT token has.So it is something linked to open id connect and oauth using Okta. I tried searching but unable to find out such token in the URL:
https://openid.net/specs/openid-connect-core-1_0.html#RFC6750
https://developer.okta.com/blog/2018/11/13/create-and-verify-jwts-with-node
https://github.com/okta/okta-oidc-js/tree/master/packages/oidc-middleware
https://developer.okta.com/blog/2019/10/03/painless-node-authentication
Everywhere i can see JWT access token and not the above type of token. Could any one please help as i am using Okta for the first time using Node and Express.
Thank you for your concern in advance :)

Google oauth2.0 405 error

Im trying to use google oauth using the below link but get a 405 error,
Can you please let me know if the parameters are correct?
client_id = changed to a diff value
response_type = code
scope= openid%20email
redirecturl = given the value based on what I registered in console.developers.com
login_hint = my gmail id..
https://accounts.google.com/o/oauth2/token?
client_id=690178314820-85fvo4eq56se4mppdaf0pt6tnnjo552&
response_type=code&
scope=openid%20email&
redirect_uri=http://test.webfactional.com&
state=security_token%3D138r5719ru3e1%26url%3Dhttps://oa2cb.example.com/myHome&
login_hint=myemail#gmail.com
I made the above get requests in the browser..
There are a few steps to getting access to Google its easer for me to show you the full flow. My guess is you are stuck on step two because your not sending it as a post.
Step 1: Ask for access
https://accounts.google.com/o/oauth2/auth?client_id={clientid}.apps.googleusercontent.com&redirect_uri={From console}&scope=openid%20email&response_type=code
This just displays the window asking them to approve you. Once the user has approved access you get a one time Authentication Code.
Step 2: Exchange Authentication Code for AccessToken and RefreshToken. Note this needs to be sent as a HTTP POST not a HTTP Get.
https://accounts.google.com/o/oauth2/token
code={Authentication Code from step 1}&client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&redirect_uri=={From console}&grant_type=authorization_code
you should get a JSon string back looking something like this.
{
"access_token" : "ya29.1.AADtN_VSBMC2Ga2lhxsTKjVQ_ROco8VbD6h01aj4PcKHLm6qvHbNtn-_BIzXMw",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/J-3zPA8XR1o_cXebV9sDKn_f5MTqaFhKFxH-3PUPiJ4"
}
Now you can take that Access_token and use it to make your requests. But access tokens are only good for 1 hour and then they expire before that time you need to use the Refresh_token to get a new access token. Also if you are going to want to access your users data again you should save the refresh_token some place that will enable you to always access there data.
Step 3: Use Refreshtoken
https://accounts.google.com/o/oauth2/token
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&refresh_token={RefreshToken from step 2}&grant_type=refresh_token
This time you will only get the Access token back, because your refreshtoken is good until the user removes authentication or you haven't used it for 6 months.
{
"access_token" : "ya29.1.AADtN_XK16As2ZHlScqOxGtntIlevNcasMSPwGiE3pe5ANZfrmJTcsI3ZtAjv4sDrPDRnQ",
"token_type" : "Bearer",
"expires_in" : 3600
}
You can find more detailed information on this here Google 3 Legged oauth2 flow
It seems you are using wrong api, you should use https://accounts.google.com/o/oauth2/auth instead of https://accounts.google.com/o/oauth2/token.
The reason you get error 405 is https://accounts.google.com/o/oauth2/token can only be called by POST, and it is to get token. You need to get authorization code first and then exchange it for a token.
Please pay attention for this /oauth2/v3/token and /oauth2/token
I do follow guide of google at this link
It show me following
obtain Authentication Code by /o/oauth2/auth => it work, the response as example in the guide
obtain access token by /oauth2/v3/token => it is error, the status code 405 is responsed
The correct must be /oauth2/token

OAuth2 response with client_id instead refresh_token

I have two example of oauth2 clients in php, one works and the other not, it return an error instead:
([error] => unauthorized [error_description] => An Authentication object was not found in the SecurityContext).
My question is, when it should a oauth2 server returns an access token response with client_id and when should it return a response with refresh_token?
My working request is:
string(130) "{"access_token":"b91f15ed-436f-470d-8d9e-bf245c5373ae","token_type":"bearer","expires_in":25209,"scope":"read","client_id":"tonr"}"
My not working request is:
string(126) "{"access_token": "eaa3c66ae1", "token_type": "bearer", "expires_in": 31536000, "refresh_token": "69f9c2cb29", "scope": "user"}"
Since it just changes client_id and refresh_token, when should it come one and when should it come another?
The refresh tokens are managed by the third party app you are using to get the access_token. That been said you can't directly request a refresh token.

Migrating from YouTube ClientLogin to OAuth 2.0

I have an app that uploads Video to YouTube to a specific YouTube channel (meaning, not to any individual user's channel, but to a single channel, for which I have the Username and Password).
In the ClientLogin my server-side process provided YouTube with the U/P and everything moved ahead. However, that's being deprecated and I'm looking to upgrade to OAuth 2.0 (as per their recommendation), however, the documentation insists on there being a redirect URI, for when the user has logged in. It doesn't seem to explain how to bypass the user login (since the user has nothing to log into, or any credentials to log in *with... the app is designed to take their video and upload it to OUR channel). So, what I need is to bypass the user being asked anything, and for YouTube to simply take my channel credentials and give me back the token for me to do the upload with.
I realize that this is a totally standard and non-controversial procedure, so I *MUST be missing something obvious, but I just can't suss out what that is.
So, my question is, how do I skip the user dialog-> redirect and just provide youtube with credentials for it to accept and then upload my video in OAuth 2.0?
What I'm really after is to do follow the DirectUpload approach here:
https://developers.google.com/youtube/2.0/developers_guide_protocol#AuthSub_Authentication_Flow
And to have retrieved the user Token silently behind the scenes.
TIA
There really is no way (that I've found) to completely bypass visiting an external page to authorize the OAuth2.0 access.
The closest I have come is to create an "Installed Application" project on code.google.com/apis/console and use the device methodology.
You will receive a Client ID and Client Secret. These will be used later.
Ideally you would generate a developer key, though I don't believe this to be required at this time, through code.google.com/apis/youtube/dashboard/
I use JSON notation for headers and responses, it should be easy to adapt to your language of choice.
First make a POST request to accounts.google.com/o/oauth2/device/code with the headers
{
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length,
'X-GData-Key': 'key=YOUR_DEVELOPER_KEY'
}
and the data containing:
{
client_id: 'YOUR_CLIENT_ID',
scope: 'https://gdata.youtube.com'
}
where YOUR_CLIENT_ID is the client ID you obtained for the google apis project you set up earlier.
You will get a response like this:
{
"device_code" : "4/Pj8m71w5XuEMTT0ZwOJVgvlTfF4Q",
"user_code" : "5wtw67wm",
"verification_url" : "http://www.google.com/device",
"expires_in" : 1800,
"interval" : 5
}
If you don't visit www.google.com/device (defined by the "verification_url" field) within 30 minutes (1800 seconds per the "expires_in" response field), you will have to perform this first request again.
On the www.google.com/device page, you will be asked to login if you aren't already and then enter the verification code (defined by the "user_code" response field). You will be presented with a request to authorize the application and a list of permissions the app is requesting.
You want to store (at least temporarily) the value for the "device_code" field. This will be used when requesting an access token and refresh token.
Now that the permission has been granted, we can request an access/refresh token pair. This only needs to happen once provided you store the refresh token.
To request the access/refresh token pair you must make a POST request to accounts.google.com/o/oauth2/token with the headers
{
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length,
'X-GData-Key': 'key=YOUR_DEVELOPER_KEY'
}
and the data
{
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
code: 'YOUR_DEVICE_CODE',
grant_type: 'http://oauth.net/grant_type/device/1.0'
}
The response will look like this
{
"access_token" : "YOUR_ACCESS_TOKEN",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "YOUR_REFRESH_TOKEN"
}
This specifies that the access token expires in 3600 seconds (60 minutes) and what your current access token is and what the refresh token is.
You want to store the access token for use with your current session and the refresh token for future sessions.
When making an API request, you will want to include the access token in the Authorization header field as well as including the developer key as we have been all along.
For uploading a video, I used these headers:
{
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'X-GData-Key': 'key=YOUR_DEVELOPER_KEY',
'Slug': 'video.mp4',
'Content-Type': 'multipart/related; boundary="f897a6d"',
'Content-Length': post_length,
'Connection': 'close'
}
You can refresh your access token at any time, not just when the old one expires. To refresh your access token, you make a POST request to accounts.google.com/o/oauth2/token with the headers
{
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length,
'X-GData-Key': 'key=YOUR_DEVELOPER_KEY'
}
and the data
{
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
refresh_token: 'YOUR_REFRESH_TOKEN',
grant_type: 'refresh_token'
}
You will get a response like this
{
"access_token" : "YOUR_NEW_ACCESS_TOKEN",
"token_type" : "Bearer",
"expires_in" : 3600
}
where YOUR_NEW_ACCESS_TOKEN is the new token for you to use in your future requests.

Resources