How To Get Google User Profile Info Using Access Token From OAuth? - reactjs

I am using ReactJS on the frontend: I successfully retrieved the access token from Google's Oauth service, but it doesn't give me any profile information for the 'current user'.
I tried using the /userInfo endpoint, ?access_token={my_access_token} query str, and some other solutions but I keep getting weird errors.
Currently I have:
const { access_token, refresh_token } = res.data; // now I have valid access_token
let userInfo = await axios.get("https://www.googleapis.com/oauth2/v3/userinfo",
{
headers: {
Authorization: `Bearer ${access_token}`
}
}); // ERROR WHEN MAKING THIS CALL.
My specific 401 error is as follows:
If there are better ways of getting user info (such as first/last name, email, etc. some sort of unique ID) please let me know.

You shouldnt rely on the user info endpoint to get user profile informaiton. As long as you are requesting the profile scope from the user, or even email. you should go though the People api. This will give you access to all of the users profile data.
GET https://people.googleapis.com/v1/people/me?personFields=names HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN]
Accept: application/json
response
{
"resourceName": "people/117dd2004755326722775346",
"etag": "%EgUBAi43PRoEAQIFBddyIMR3BzQkR2cnI1ZGc9",
"names": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "117200155326727753146"
}
},
"displayName": "Linda Lawton",
"familyName": "Lawton",
"givenName": "Linda",
"displayNameLastFirst": "Lawton, Linda",
"unstructuredName": "Linda Lawton"
},
{
"metadata": {
"source": {
"type": "CONTACT",
"id": "3faa96eb0118baa4be"
}
},
"displayName": "Linda Lawton",
"familyName": "Lawton",
"givenName": "Linda",
"displayNameLastFirst": "Lawton, Linda",
"unstructuredName": "Linda Lawton"
}
]
}

Related

How to make authorized "post" request strapi graphql apollo nextjs

I am building an ecommerce website using strapi, apollo, graphql, nextjs, when an authenticated users ordering they need to send jwt token using headers but I am little confused how to do that. Here is my code on apollographql playground.
mutation Mutation($data: OrderInput!) {
createOrder(data: $data) {
data {
id
attributes {
name
phone
products {
data {
id
attributes {
price
name
media {
data {
attributes {
url
}
}
}
}
}
}
status
details
createdAt
user {
data {
attributes {
username
}
}
}
}
}
}
}
When I do that it is giving following error.
{
"errors": [
{
"message": "Forbidden access",
"extensions": {
"error": {
"name": "ForbiddenError",
"message": "Forbidden access",
"details": {}
},
"code": "FORBIDDEN"
}
},
{
"message": "Forbidden access",
"extensions": {
"error": {
"name": "ForbiddenError",
"message": "Forbidden access",
"details": {}
},
"code": "FORBIDDEN"
}
}
],
Without authorisation its working fine, but I do not know how to insert jwt token
Looks fine to me. You probably inserted an expired token. Have you tried turning on the create permission for authenticated role?
Finally I solved the issue by allowing "find" method in user permission tab.

Next-Auth | When user object have too many items then session request is without data

I will try to explain my problem as best as possible for me.
I'm using Strapi as a backend and Nextjs as a frontend.
For the authentication I using NextAuth.
[...nextauth].js:
const options = {
providers: [
Providers.Credentials({
name: 'Credentials',
credentials: {
username: { label: "Email", type: "email", placeholder: "jsmith" },
password: { label: "Password", type: "password" }
},
authorize: async (credentials) => {
try {
const user = await axios.post(`${process.env.NEXT_PUBLIC_API_URL}/auth/local`, {
identifier: credentials.username,
password: credentials.password,
});
if (user.data) {
return user.data
} else {
return null
}
} catch (error) {
const errorMessage = error.response.data.message[0].messages[0].message
throw new Error(errorMessage)
}
}
}),
],
database: process.env.NEXT_PUBLIC_DATABASE_URL,
session: {
jwt: true,
},
callbacks: {
jwt: async (token, user) => {
if (user) {
token.jwt = user.jwt;
token.user = user.user;
}
return Promise.resolve(token);
},
session: async (session, token) => {
session.jwt = token.jwt;
session.user = token.user;
return Promise.resolve(session);
},
},
pages: {
signIn: '/login',
error: '/login'
},
};
const Auth = (req, res) =>
NextAuth(req, res, options);
export default Auth;
When I send form with identifier and password I getting session response with user data and jwt.
Everything working well, but if user objects have few more objects assigned to him, then something goes wrong and the session is empty.
Example:
I creating in Strapi simple collection with just two fields - image field, and owner (relation to user). Every response with image contents few lines:
"photo": {
"_id": "60ca03fa20bd43033a53950e",
"name": "Zrzut ekranu 2021-06-16 o 14.59.48.png",
"alternativeText": "",
"caption": "",
"hash": "Zrzut_ekranu_2021_06_16_o_14_59_48_2bc223567b",
"ext": ".png",
"mime": "image/png",
"size": 170.69,
"width": 668,
"height": 636,
"url": "/uploads/Zrzut_ekranu_2021_06_16_o_14_59_48_2bc223567b.png",
"formats": {
"thumbnail": {
"name": "thumbnail_Zrzut ekranu 2021-06-16 o 14.59.48.png",
"hash": "thumbnail_Zrzut_ekranu_2021_06_16_o_14_59_48_2bc223567b",
"ext": ".png",
"mime": "image/png",
"width": 164,
"height": 156,
"size": 14.92,
"path": null,
"url": "/uploads/thumbnail_Zrzut_ekranu_2021_06_16_o_14_59_48_2bc223567b.png"
},
"small": {
"name": "small_Zrzut ekranu 2021-06-16 o 14.59.48.png",
"hash": "small_Zrzut_ekranu_2021_06_16_o_14_59_48_2bc223567b",
"ext": ".png",
"mime": "image/png",
"width": 500,
"height": 476,
"size": 121.79,
"path": null,
"url": "/uploads/small_Zrzut_ekranu_2021_06_16_o_14_59_48_2bc223567b.png"
}
},
When I add 1 or 2 items with image and try to login to user who own that items then everything is fine, I can log in and receive full user object and jwt token.
But when I add 3 items there, session object is empty, and I can't log in. I do not receiving user object and jwt token.
With 3 items
With 2 items
When I using postman, even with 50 items response is good and include full user object and jwt token.
I think is because response is too large or something like that, but I have no clue how to deal with it.
I working on localhost (both - frontend and backend) on MacOS.
Is there anyone who can help me find a solution for that problem?
Kind Regards,
GP
The reason of above issue is that in api response is passed to many data, and next-auth store that all data in JWT, and JWT is stored in full in cookie, cookie is limited to 4096 bytes, and that simply brake that limit and response.
The simplest way to sort it out is to save only most important data in JWT.
You can do that in callback function.

Excel Add-In keeps getting 401 error when trying to access Dynamics 365 Web Api

I am trying to develop a word add in in React with Typescript that allows me to access the dynamics 365 Web Api. The best example I've actually found was in a sample excel add in that accesses the graph api using MSAL 2.0 here https://github.com/OfficeDev/PnP-OfficeAddins/tree/master/Samples/auth/Office-Add-in-Microsoft-Graph-React. If I can get a successful get request to my Dynamics 365 api after modifying the example code I will port the code over to my Word Add in.
However I keep getting a 401 error when trying to go to https://saltrial.crm.dynamics.com/api/data/v9.1/
I get a response back when I simply paste this in a browser, but inside the add in I get 401 unauthorized. I also get 401 unauthorized when I paste the token received from the add in into postman with the header of Bearer + token. I have gotten a successful Access token however when I selected
I will show you my setup in Azure AD.... I have a client secret setup, but am not using it in my add in code.
Manifest
{
"id": "35c3a758-0edb-45f6-a97d-9c7180decd73",
"acceptMappedClaims": null,
"accessTokenAcceptedVersion": 2,
"addIns": [],
"allowPublicClient": true,
"appId": "4f7xxxxxxxxxxxxxxxxxxxxxx310bf0",
"appRoles": [],
"oauth2AllowUrlPathMatching": false,
"createdDateTime": "2021-01-24T07:09:12Z",
"disabledByMicrosoftStatus": null,
"groupMembershipClaims": null,
"identifierUris": [
"api://localhost:3000/4fxxxxxxxxxxxxxxxxxxxxxxx"
],
"informationalUrls": {
"termsOfService": null,
"support": null,
"privacy": null,
"marketing": null
},
"keyCredentials": [],
"knownClientApplications": [],
"logoUrl": null,
"logoutUrl": null,
"name": "TrySSO",
"oauth2AllowIdTokenImplicitFlow": true,
"oauth2AllowImplicitFlow": true,
"oauth2Permissions": [
{
"adminConsentDescription": "Enable Office to call the add-in's web APIs with the same rights as the current user.",
"adminConsentDisplayName": "Office can act as the user",
"id": "5b3a4e4a-e55e-45ba-820b-ea16efbe3d5f",
"isEnabled": true,
"lang": null,
"origin": "Application",
"type": "User",
"userConsentDescription": "Enable Office to call the add-in's web APIs with the same rights that you have.",
"userConsentDisplayName": "Office can act as you",
"value": "access_as_user"
}
],
"oauth2RequirePostResponse": false,
"optionalClaims": null,
"orgRestrictions": [],
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [
{
"customKeyIdentifier": null,
"endDate": "2299-12-31T05:00:00Z",
"keyId": "570axxxxxxxxxxxxxxxxxxxxxxxxxxbcd1",
"startDate": "2021-01-28T04:11:05.086Z",
"value": null,
"createdOn": "2021-01-28T04:11:06.027737Z",
"hint": "mm-",
"displayName": "wordaddinsecret"
}
],
"preAuthorizedApplications": [
{
"appId": "ea5a67f6-b6f3-4338-b240-c655ddc3cc8e",
"permissionIds": [
"5b3a4e4a-e55e-45ba-820b-ea16efbe3d5f"
]
},
{
"appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c",
"permissionIds": [
"5b3a4e4a-e55e-45ba-820b-ea16efbe3d5f"
]
},
{
"appId": "57fb890c-0dab-4253-a5e0-7188c88b2bb4",
"permissionIds": [
"5b3a4e4a-e55e-45ba-820b-ea16efbe3d5f"
]
},
{
"appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3",
"permissionIds": [
"5b3a4e4a-e55e-45ba-820b-ea16efbe3d5f"
]
}
],
"publisherDomain": "salnewtrial.onmicrosoft.com",
"replyUrlsWithType": [
{
"url": "https://localhost:3000/login/login.html",
"type": "Spa"
},
{
"url": "https://login.microsoftonline.com/common/oauth2/nativeclient",
"type": "InstalledClient"
},
{
"url": "https://localhost:3000/login.html",
"type": "Web"
}
],
"requiredResourceAccess": [
{
"resourceAppId": "00000007-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "78ce3f0f-a1ce-49c2-8cde-64b5c0896db4",
"type": "Scope"
}
]
},
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "14dad69e-099b-42c9-810b-d002981feec1",
"type": "Scope"
},
{
"id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182",
"type": "Scope"
},
{
"id": "37f7f235-527c-4136-accd-4a02d197296e",
"type": "Scope"
},
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
}
]
}
],
"samlMetadataUrl": null,
"signInUrl": null,
"signInAudience": "AzureADMyOrg",
"tags": [],
"tokenEncryptionKeyId": null
}
Inside my login.ts in excel add in
(() => {
// The initialize function must be run each time a new page is loaded
Office.initialize = () => {
const msalInstance = new PublicClientApplication({
auth: {
clientId: "4f7f40ec-xxxxxxxxx-5d6b18310bf0",
authority: "https://login.microsoftonline.com/cd77a053-xxxxxxxxxx3402c0fd62", *This is tenant id
redirectUri: "https://localhost:3000/login/login.html", // Must be registered as "spa" type
},
cache: {
cacheLocation: "localStorage", // needed to avoid "login required" error
storeAuthStateInCookie: true, // recommended to avoid certain IE/Edge issues
},
});
// handleRedirectPromise should be invoked on every page load
msalInstance
.handleRedirectPromise()
.then((response) => {
// If response is non-null, it means page is returning from AAD with a successful response
if (response) {
Office.context.ui.messageParent(
JSON.stringify({ status: "success", result: response.accessToken })
);
} else {
// Otherwise, invoke login
msalInstance.loginRedirect({
scopes: [
"user.read",
"files.read.all",
"https://saltrial.crm.dynamics.com//user_impersonation",
],
});
}
})
.catch((error) => {
const errorData: string = `errorMessage: ${error.errorCode}
message: ${error.errorMessage}
errorCode: ${error.stack}`;
Office.context.ui.messageParent(
JSON.stringify({ status: "failure", result: errorData })
);
});
};
})();
Here is my API Call in Add in
import axios from 'axios';
export const getGraphData = async (url: string, accesstoken: string) => {
const response = await axios({
url: url,
method: 'get',
headers: {'Authorization': `Bearer ${accesstoken}`,
'OData-MaxVersion': '4.0',
'OData-Version': '4.0',
"Accept": "application/json",
"Content-Type": "application/json; charset=utf-8",
}
});
return response;
};
Code that calls my api function and passes the scopes and dynamics url. I console log the access token and put it into postman with header Bearer token, I get 401. Also the add-in displays 401 unauthorized in the task pane....Ignore any naming of functions referring to the graph api, I'm hitting the dynamics 365 api and hoping I don't get the 401 error. Thanks.
getFileNames = async () => {
this.setState({ fileFetch: "fetchInProcess" });
getGraphData(
// Get the `name` property of the first 3 Excel workbooks in the user's OneDrive.
"https://saltrial.crm.dynamics.com/api/data/v9.1/WhoAmI",
this.accessToken
)
.then(async (response) => {
await writeFileNamesToWorksheet(response, this.displayError);
this.setState({ fileFetch: "fetched", headerMessage: "Success" });
})
.catch((requestError) => {
// If this runs, then the `then` method did not run, so this error must be
// from the Axios request in getGraphData, not the Office.js in
// writeFileNamesToWorksheet
console.log("Access Token >>>>>>>>>>>>>>>>> ", this.accessToken);
this.displayError(requestError);
});
};

what is 'code' parameter in django-rest-social-auth?

I am new in Django and working on django-rest-social-auth.
I want to implement social login in my app.(frontend- angular, Backend- Django)
but I am not getting what is the code parameter below request.
POST /api/login/social/token/
input:
{
"provider": "facebook",
"code": "AQBPBBTjbdnehj51"
}
output:
{
"token": "68ded41d89f6a28da050f882998b2ea1decebbe0"
}
POST /api/login/social/token_user/
input:
{
"provider": "facebook",
"code": "AQBPBBTjbdnehj51"
}
output:
{
"username": "Alex",
"email": "user#email.com",
// other user data
"token": "68ded41d89f6a28da050f882998b2ea1decebbe0"
}

Ask for how to get user profile after callback

My web application is using Single Sign On (SSO) service from IBM Bluemix. This is the credentials info of my SSO service:
{
"SingleSignOn": [
{
"credentials": {
"secret": "MYSECRET",
"tokenEndpointUrl": "https://adminwebsso-jjjfvxi6wy-cq17.iam.ibmcloud.com/idaas/oidc/endpoint/default/token",
"authorizationEndpointUrl": "https://adminwebsso-jjjfvxi6wy-cq17.iam.ibmcloud.com/idaas/oidc/endpoint/default/authorize",
"issuerIdentifier": "adminwebsso-jjjfvxi6wy-cq17.iam.ibmcloud.com",
"clientId": "MYCLIENTID",
"serverSupportedScope": [
"openid"
]
},
"syslog_drain_url": null,
"volume_mounts": [],
"label": "SingleSignOn",
"provider": null,
"plan": "professional",
"name": "VA-Admin-Console-R1-SSO",
"tags": [
"security",
"ibm_created",
"ibm_dedicated_public"
]
}
]
}
From my Application, I redirect to Login page of IBM like URL:
https://adminwebsso-jjjfvxi6wy-cq17.iam.ibmcloud.com/idaas/oidc/endpoint/default/authorize?response_type=code&client_id=MYCLIENTID&redirect_uri=http://localhost/callbackā‰»ope=openid%20openid
After login success IBM redirect to my web application, I can get parameter "code" from callback URL (http://localhost/callback?scope=openid&code=bngM6aV5cYHAvhv7wLAM5QSWFDARn7).
From there, I use the "code" to to get user profile. I have try to use AJAX to get user profile:
var settings = {
"async": true,
"crossDomain": true,
"url": "https://idaas.ng.bluemix.net/sps/oauth20sp/oauth20/token",
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded",
"authorization": "Basic RXhhbXBsZV9BcHBJRDpWUFlndEdXRlRvYVpZSUNTRzhJeVZFV000bUZicGpsU2t4RlRRbzlySkRGZDdzckc=",
"cache-control": "no-cache"
},
"data": {
"client_secret": "MYSECRET",
"grant_type": "authorization_code",
"redirect_uri": "http://localhost/callback",
"code": "bngM6aV5cYHAvhv7wLAM5QSWFDARn7",
"client_id": "MYCLIENTID"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
From ajax post above, I have tried to use the "code" from callback, but I've got an error message:
500 Error: Failed to establish a backside connection
I've got stuck here and don't know how to get user profile from SSO.
With in the SSO Service there are some inbuilt macros that can be used to get the user name, for more information please see.
https://console.bluemix.net/docs/services/SingleSignOn/customizing_pages.html#customizing_pages
#USERNAME# The user ID of the authenticated user.

Resources