How can we pass headers arguments with whitespaces in graphql? - graphql

API is working absolutely fine in graphql playground.
But when I tested the same API with the same data in postman it gave me an error.
{
"errors": [
{
"message": "Context creation failed: Permission denied",
"statusCode": 500
}
]
}
I was passing the access token in the header
like:
{"authorization":"Bearer accesstoken"}
In terms of postman data is going in this format
authorization: Bearer accesstoken
The issue is with the white space in the Bearer and access token
Is there any way we can pass a value with whitespaces in header?
I have tried using %20 and _.

Related

Xbox Live Authentication Request Returns Code "400 Bad Request" When Using Access Token Obtained Using MSAL (Swift)

I am trying to authenticate with Xbox Live using an access token obtained using the MSAL authentication library for Swift.
All I am getting as a response is Response Code 400, instead of the expected JSON response containing an Xbox Live token.
I am sending the following request:
{
"Properties": {
"AuthMethod": "RPS",
"SiteName": "user.auth.xboxlive.com",
"RpsTicket": "d=(access token)"
},
"RelyingParty": "http://auth.xboxlive.com",
"TokenType": "JWT"
}
It is a POST request to https://user.auth.xboxlive.com/user/authenticate
It has these headers: Content-Type: application/json and Accept: application/json.
I am using the Swift MSAL library: https://github.com/AzureAD/microsoft-authentication-library-for-objc
My code for getting the access token looks like this:
let MSConfig = MSALPublicClientApplicationConfig(clientId: AppGlobals.clientID)
let MSApplication = try? MSALPublicClientApplication(configuration: MSConfig)
let MSScopes = ["User.Read"]
let MSWebviewParameters = MSALWebviewParameters()
let MSInteractiveParameters = MSALInteractiveTokenParameters(scopes: MSScopes, webviewParameters: MSWebviewParameters)
MSApplication?.acquireToken(with: MSInteractiveParameters, completionBlock: { (result, error) in
guard let MSAuthResult = result, error == nil else {
print("Error while authing: \(error!.localizedDescription)")
return
}
let receivedMSAccessToken = MSAuthResult.accessToken
let receivedMSAccountIdentifier = MSAuthResult.account.identifier
})
The code for obtaining an access token works as expected, and I get an access token once I log in using Microsoft. I am then using the access token obtained on line let receivedMSAccessToken = MSAuthResult.accessToken as the access token on the request line "RpsTicket": "d=(access token)". However, I am still getting error 400 (Bad Request).
What can I do to fix this?

laravel passport: how to validate bearer authorization code - without sign in

I did request:
{
"grant_type": "client_credentials",
"client_id": 8,
"client_secret": "XXNKXXqJjfzG8XXSvXX1Q4pxxnkXmp8tT8TXXKXX",
"redirect_uri": "",
"scope": "*"
}
Then received response below:
{
"token_type": "Bearer",
"expires_in": 31536000,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGcXXXJSUzI1NiIsImp0aSI6ImEzYjJhZmU5OTYzMTE5MDAyZDAwZmEzNzU0ZGY3ZTRkMTgwYzhlYWRmNGQyOGU5MTI4YjAyYjJmYWQxZjY1NjUzMzAyZjNlZTI4MTgxMDFhIn0.eyJhdWQiOiI4IiwianRpIjoiYTNiMmFmZTk5NjMxMTkwMDJkMXXXYTM3XXXkZjdlNGQxODBjOGVhZGY0ZDI4ZTkxMjhiMDJiMmZhZDFmNjU2NTMzMDJmM2VlMjgxODEwMWEiLCJpYXQiOjE1NDAwMTQxNTUsIm5iZiI6MTU0MDAxNDE1NSwiZXhwIjoxNTcxNTUwMTU1LCJzdWIiOiIiLCJzY29wZXMiOltdfQ.sNSYywfBf27yAojqZclpjliysbQARlYFktzanTMecXXXIai5DgJY0sKhGpHktP5cqirYdemoFKy2nOxzZ8g29gCQQ63zmxe3vpbDz1GAdrjCDWoUlwSXXXHx4VIsdSIzVdi9XyvPKaLKMdoL6nFeWgpgXKGIvHKdiHjKgQbY_08Qa6JMN5Up27qmIOQoXJNAf1nuXvBMabUU_Js7VNspwPfdC8nMZ5zhK1A_c32_lDRtHqkhDfqqBXdUB-inx-zixhn2ODC4b4tkdj7XXXXlVKFxHxKM3aVOMFlmKhypSDwIUB0dPsN8iHcLzkl1yjzRQcOvQEj5BXWLkLCPdkiX2YJuFiWGUm_nxiYoIRV3ptJDeBI5OJI870JTOwBfJePrHTbXmhbjNSQSflLtiOV34wbPQZWH3KMKcsGVYvXXX3rcO5cbZWeeJLGPPYYO-_AWDmdAm-Qsb6Tw1sPxEZRw0dw3zBHnLVrEK9GXXXN2U5wE9Ka3id8ecOJSXSD39X1PyZUB9dJTidmbiWYWgskSTsqLuWfzXXXtlXkb1iOO37kT_Y5zr71Wp1RJ1Fp38yIyHI6fR9hKqeNALSqhv2ALmcSMQsFGTtPG98lGulu-vRJJhgMJ3C3fSTljN7o9BM7Jz-h0ymxC8sSMSNsXakK1qu40vD40zRJMB09sBPjIAVo"
}
which i suppose to use it in authorization header to consume my API, as follow:
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGcXXXJSUzI1NiIsImp0aSI6ImEzYjJhZmU5OTYzMTE5MDAyZDAwZmEzNzU0ZGY3ZTRkMTgwYzhlYWRmNGQyOGU5MTI4YjAyYjJmYWQxZjY1NjUzMzAyZjNlZTI4MTgxMDFhIn0.eyJhdWQiOiI4IiwianRpIjoiYTNiMmFmZTk5NjMxMTkwMDJkMXXXYTM3XXXkZjdlNGQxODBjOGVhZGY0ZDI4ZTkxMjhiMDJiMmZhZDFmNjU2NTMzMDJmM2VlMjgxODEwMWEiLCJpYXQiOjE1NDAwMTQxNTUsIm5iZiI6MTU0MDAxNDE1NSwiZXhwIjoxNTcxNTUwMTU1LCJzdWIiOiIiLCJzY29wZXMiOltdfQ.sNSYywfBf27yAojqZclpjliysbQARlYFktzanTMecXXXIai5DgJY0sKhGpHktP5cqirYdemoFKy2nOxzZ8g29gCQQ63zmxe3vpbDz1GAdrjCDWoUlwSXXXHx4VIsdSIzVdi9XyvPKaLKMdoL6nFeWgpgXKGIvHKdiHjKgQbY_08Qa6JMN5Up27qmIOQoXJNAf1nuXvBMabUU_Js7VNspwPfdC8nMZ5zhK1A_c32_lDRtHqkhDfqqBXdUB-inx-zixhn2ODC4b4tkdj7XXXXlVKFxHxKM3aVOMFlmKhypSDwIUB0dPsN8iHcLzkl1yjzRQcOvQEj5BXWLkLCPdkiX2YJuFiWGUm_nxiYoIRV3ptJDeBI5OJI870JTOwBfJePrHTbXmhbjNSQSflLtiOV34wbPQZWH3KMKcsGVYvXXX3rcO5cbZWeeJLGPPYYO-_AWDmdAm-Qsb6Tw1sPxEZRw0dw3zBHnLVrEK9GXXXN2U5wE9Ka3id8ecOJSXSD39X1PyZUB9dJTidmbiWYWgskSTsqLuWfzXXXtlXkb1iOO37kT_Y5zr71Wp1RJ1Fp38yIyHI6fR9hKqeNALSqhv2ALmcSMQsFGTtPG98lGulu-vRJJhgMJ3C3fSTljN7o9BM7Jz-h0ymxC8sSMSNsXakK1qu40vD40zRJMB09sBPjIAVo
Accept:application/json
Content-Type:application/json
I'm able to catch the bearer token with: $token = $request->bearerToken(); in my controller
But I have difficulties to validate it, anyone know how to validate that token?
what i'm trying to achieve is quite simple, if the Bearer token valid then continue... if not then throw 403.
**I'm not using user authentication (no user) so I can't put middleware Auth::api in route (unless you tell me this is possible to validate token only without user).*
Try this and let me know if any error occurs.
Add the following in App/Http/Kernel.php file in protected $routeMiddleware array:
'client.credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
Now in your controller add the following in the beginning:
public function __construct()
{
$this->middleware('client.credentials')->only(['']);
}
add your function names in the array to check if the request has an Authorization header with a token for the function.You do not need to do anything else.
You can check after, using postman with an incorrect token an error will return from the api as the result.
Also as a tip , do not put your "client_secret" on client side , it should not get in the wrong hands.
Use the following to generate a token for the user:
$user = User::where('email',$email)->where('password',$password)->firstOrFail();
$token = $user->createToken('Token')->accessToken;

Use token received from JavaScript client to create a social connection on the server

I have a webpage using PHP/JavaScript that can successfully do the Google Signin process on the client side. I would like to then forward the obtained token to the backend which uses Spring-Social to create a social connection and be able to call on the APIs to which the app has been authorized.
I managed to do exactly this with both Facebook (OAUTH2) and Twitter (OAUTH1) both working flawlessly but for Google I always get a 401 response when trying to create the connection.
The code in the server is like this:
AccessGrant accessGrant = new AccessGrant(accessToken);
connection = ((OAuth2ConnectionFactory<?>) connectionFactory).createConnection(accessGrant);
The code in the client something like this:
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId());
console.log('Name: ' + profile.getName());
console.log('Email: ' + profile.getEmail());
var access_token = googleUser.getAuthResponse().id_token;
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost/signin/google');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
console.log('Signed in as: ' + xhr.responseText);
console.log('access_token=' + access_token);
};
xhr.send('access_token=' + access_token);
}
Most of the latter is copied from the Google documentation on how to authenticate with a backend server found here: https://developers.google.com/identity/sign-in/web/backend-auth
I've traced the calls inside spring-social-google and they lead to a REST call to https://www.googleapis.com/oauth2/v2/userinfo which is the one that replies 401 and the following JSON:
{
"error": {
"errors": [{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}],
"code": 401,
"message": "Invalid Credentials"
}
}
I've tried to call on this same REST API myself and I also get the same response, so it does not seem to be an issue of spring-social-google not sending the token properly as I've read on some other posts.
I believe that the issue is somehow related to the fact that the JavaScript API is giving me an "id_token" and the REST API is expecting an "access_token". However, I am not finding a way to obtain the access token as something separate from the id_token and the Google documentation does send the id_token to the backend. There is an "access_token" property alongside the used "id_token" property in googleUser.getAuthResponse() but it is coming back undefined.
This doc is of course not aimed at spring-social so I am not saying it is incorrect, I am just left wondering what is the proper way to achieve this.
Is spring-social at fault by not being able to deal with the id_token?
Am I at fault not seeing some clear way to get the access_token?
Anyway, I feel like I am somehow close but still the solution seems well out of grasp.
Thank you!
Well, I found it. It seems that writing the whole thing down really tripped something in my brain...
The issue is in fact that the id_token cannot take the place of the access_token. To my taste, Google documentation could be a little more explicit about this in the example they show but they do end up explaining it in the actual client reference at https://developers.google.com/identity/sign-in/web/reference
The key is the boolean parameter to getAuthResponse() which is optional and defaults to false. From the doc:
includeAuthorizationData Optional: A boolean that specifies whether
to always return an access token and scopes. By default, the access
token and requested scopes are not returned when fetch_basic_profile
is true (the default value) and no additional scopes are requested.
By setting this to true in my JS the access_token field which was previously undefined was populated and with this token one can access the /oauth2/v2/userinfo endpoint and spring-social-google can correctly create a connection just like the other providers.
I hope this helps someone else at least.

"invalid request" "Required parameter is missing: grant_type" error trying to obtain oAuth2 access token with JWT

Per Google's documentation on using service account, this is what I did so far.
Created JWT (json web token) with following payload.
{"iss":"XXXXXXXX.gserviceaccount.com",
"aud":"https://www.googleapis.com/oauth2/v4/token",
"iat":"1465531250",
"exp":"1465534850",
"scope":"email profile}
Using Postman, I did http post as follows in the hope of getting back the oAuth2 access token.
URL: https://www.googleapis.com/oauth2/v4/token
Headers:
Content-Type: application/x-www-form-urlencoded
grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion: <the JWT generated in step 1 above>
Instead, I got error response as follows.
{
"error": "invalid_request",
"error_description": "Required parameter is missing: grant_type"
}
Can someone find what is wrong with my request?
I have even tried a different endpoint of "https://accounts.google.com/o/oauth2/token" with grant_type of "authorization_code" as well as "http://oauth.net/grant_type/jwt/1.0/bearer". That too returned the same exact error!
The grant_type and assertion parameters are not passed as request headers but as post request parameters (grant_type=xxxxxx&assertion=yyyyy)

YouTube Retrieve a Refresh Token?

I am sending a delete request to the youtube api but I am receiving a 401 error (unauthorized). I'm not sure why. My key is set properly, I am able to access the analytics of the youtube channel. This is my code that fires on a button click
jQuery.ajax({
type: 'DELETE',
// must set api key
url: 'https://www.googleapis.com/youtube/v3/videos?id='+ thisUniqueID + '&key={<?php echo $oAuth2Key; ?>}',
});
I've used alert to check that my auth key is set properly (shown below).
alert('<?php echo $oAuth2Key; ?>');
and I can see in the returned address with the error that the url is proper. What could be the issue?
It looks like I need a refresh token. This is straight out of the docs: The API will return an HTTP 401 response code (Unauthorized) if you submit a request to access a protected resource with an expired access token. The following section explains how to refresh an access token.
Is there an easy way to retrieve a refresh token at the same time that I send a delete request? If not is there an easy way to retrieve one with out the need for the client id/client secret etc.
I somehow have gotten a key for analytics, but when I go to delete a video the key is not valid.
I would suggest you to use Data API v3 instead.
Yes, you can do AJAX calls. Here's the videos->delete call.
DELETE https://www.googleapis.com/youtube/v3/videos?id=VIDEO_ID&key={YOUR_API_KEY}
You find the documentation for using authorization at:
https://developers.google.com/youtube/v3/guides/authentication
You use the API key for access to public data !
Since you want to delete a video, you must use the access_token. An access_token is valid for a short time (1 hour). You can get a new one by using your refresh_token to request another one.
Store a refresh_token since it is valid until it gets revoked.
BTW.
Maybe use client.js, to handle the authorization for your requests ?
For JS, by adding:
<script src="https://apis.google.com/js/client.js?onload=googleApiClientReady"></script>
The general documentation is at:
https://developers.google.com/api-client-library/javascript/start/start-js
An code example for YouTube is at:
https://developers.google.com/youtube/v3/code_samples/javascript
For reference of the video delete method see:
https://developers.google.com/youtube/v3/docs/#videos
The listed methods are: insert, list, delete, update , rate and getRating.
The delete method might be (This is NOT tested with a valid videoID):
var requestOptions = {
id: '012345678901', // replace VIDEOID
part: 'id'
};
var request = gapi.client.youtube.videos.delete (requestOptions);
request.execute(function(response) {
console.log("RESPONSE: " + response);
});
The response using a non-existing videoId is:
[
{
"error": {
"code": -32500,
"message": "Video not found",
"data": [
{
"domain": "youtube.video",
"reason": "videoNotFound",
"message": "Video not found",
"locationType": "parameter",
"location": "id"
}
]
},
"id": "gapiRpc"
}
]

Resources