I'm creating REST API (Symfony 4, FOS Rest bundle) and for testing I'm using Postman app. Problem is that at login request I get JWT token and later, in every other request I have to pass it back as part of Authorization header, as Bearer token. And since this token changes with every login I have to manually copy/paste token value after every login (when token expires).
Can that be avoided somehow and done automatically?
First, after successful authorization - login call returned the JWT token it has to be stored into some variable. When editing login request, there is a "Tests" tab.
Here we can put JavaScript code that will be executed after request is executed, so we will enter the code like this there:
var jsonData = JSON.parse(responseBody);
if(jsonData.token) {
pm.globals.set("jwt-token", jsonData.token);
}
Or, shorter version, as #Danny Dainton suggested:
pm.globals.set("jwt-token", pm.response.json().token)
We are collecting response and storing "token" value to global variable called "jwt-token".
If you use older version of Postman this code should look a bit different - storing variable should look like:
postman.setEnvironmentVariable("jwt-token", jsonData.token);
(Here storing as environmental variable vs. global variable in example above - both types should work. Use what you need).
So now, token value will be stored. Then we have to use it with other requests.
Edit all other request that must pass JWT token. Go to "Authorization" tab, select "Bearer Token" authorization type and for value just enter {{jwt-token}} .
Again if you are using older version of Postman and don't have that "Bearer Token" type go to "Headers" tab instead, add new header with key "Authorization" and for it's value set Bearer {{jwt-token}}
That's it. Now you have to execute login request only once and JWT token will automatically be used in all other request.
And if you face some issue, you can use console to print debug info. Add in you code i.e.:
console.log(jsonData.token);
And from main menu go to View -> Show Postman Console to open console window where will you get console.log output.
Related
I'm building a react native app which uses the spotify web api. I'm using the authorization code flow to authorize a user. First I get a authorization code which can be used to obtain an access token and a refresh token. Everything works!
The problem is: an access token is only valid for a limited amount of time. That's where the refresh token comes in. I understand this concept, but I'm breaking my head about how to implement this.
Let's say a users opens the app, requests an access token and uses this for some time. Then, the user closes the app. After 15 minutes, the users opens the app again. The access token has now expired, so I need to request a new access token.
I've come op with several "solutions". Can someone point me to the correct solution?
Solution 1:
Every time the user opens the app, I request a new access token and use this. Problem: when the user uses the app longer than the valid time of the access token, I won't work anymore.
Solution 2:
I use the access token that's stored in the secure storage on every request. When a request comes back with 'access token invalid' (I don't know the exact error code but you guys know what I mean), I request a new access token with the stored refresh token, and then I send the previous command again (with the new access token). But my question here is: can I use some kind of "wrapper function" which checks the response of the request, and if the response is "access token invalid", it automatically requests a new access token and runs the previous request again.
I think certainly correct solution is solution 2,and i think its clear enough.
and for using solution 2 you need somthing like wrapper function,yes its intelligently.
so you should use interceptor:
what is interceptor ?
You can intercept requests or responses before they are handled by then or catch.
in link below there is a good example of implementing refresh token in axios interceptor:
https://gist.github.com/Godofbrowser/bf118322301af3fc334437c683887c5f
I agree that Solution 2 is the best, each time you do a request you can check to see if the Access Token has expired, and if it has then you can request a new Access Token using the Refresh Token as you mentioned and then make your request, in my own project I do this in a FormatRequestHeadersAsync method which calls a CheckAndRenewTokenAsync method where I perform the following check, here shown in C#:
if(AccessToken?.Refresh != null && (AccessToken.Expiration < DateTime.UtcNow))
{
AccessToken = await GetRefreshTokenAsync(
AccessToken.Refresh,
AccessToken.TokenType,
cancellationToken);
}
You can store the Access Token and the Refresh Token and then use something similar to this before you make each request to the API this will refresh your token and then you can store the new Access Token and the existing Refresh Token.
I am currently implementing a feature that you have the ability to save a song displayed on my iOS application (written with Swift) and this save button allows the song to be appended to the user's Spotify library. According to the Spotify Developer guide, the only scope required for this feature is user-library-modify when authorizing the app with the user. The url to be opened goes like this:
https://accounts.spotify.com/authorize/?client_id=my_client_id&response_type=code&scope=user-library-modify&redirect_uri=http://my_redirect_uri
This all works perfectly - the url is opened for the user to approve of the changes my app can make and the callback url with the required code is in the url is opened.
The next step in performing the required function is to get an exact token in order to use the api, which is done by calling the url:
https://accounts.spotify.com/api/token?grant_type=client_credentials&client_id=my_client_id&client_secret=my_client_secret&response_type=code&redirect_uri=http://my_redirect_uri&code=the_code_I_just_retrieved
With this url, a json file is returned with the new token and info with it, BUT when looking at the permitted scopes the token has, it is empty:
["scope": , "token_type": Bearer, "access_token": the_token_string, "expires_in": 3600]
Also, when I still try to perform the request it returns:
["error": {
message = "Insufficient client scope";
status = 403;
}]
In this lengthy process, what am I doing wrong? In case you are wondering, here are a few things I have tried without success:
1) Re-listing the scopes in the explicit token request
2)Adding utf-8 encoding to the redirect uri (not sure if this changes anything)
3)Adding many other scopes (although this clearly does not target the problem)
If anyone knows what I am doing wrong or has any suggestions as to what I should try, I am grateful for any helpful response!
I have found my mistake. The grant_type I have entered in my url set to client_credentials. However, this method of accessing the web API only permits the usage of publicly available data, not user info. Therefore, this method of authorization does not accept the parameter scope, forcing the spotify account service to ingnore this additional parameter. The other options DO allow accessing the user data, which are:
authorization_code, and refresh_token
The way this now has to be done is to:
1) Authorize the user regularly (with supplying the scopes) to retrieve the initial authorization code
2) Then, with this code, make the token request, but specifying the grant_type to be set as authorization_code
3) You have then received a valid access_token valid for one hour AND a refresh_token
4) Use the access_token when necessary and when this token expires, make another token request, but this time with the grant_type set as refresh_token and setting the code parameter to the previously gained refresh_token
5) You now have the next access_token and refresh_token
6) Repeat steps 4-5 until infinity
My app API requires authentication via an authentication token. In short, we send a request to a /authentication endpoint and it responds with a JSON object containing a token, like:
{"token": "xxxxxxxxxxxxxxxxxxxxxx"}
Every other API endpoint in our application requires an authentication header containing this token. Now, in Postman it's possible to do the authentication request, copy the token, open the next endpoint and paste the authentication header in manually. But this becomes tedious and time-consuming when testing lots of endpoints.
Is there a way to have Postman save and automatically add the authentication token from one request in any follow-up requests?
Even better, could Postman automatically send the /authentication request prior to any of the other requests?
Postman allows you a wide variety of options when crafting API requests.
In your case, You can create a global variable for your token when you receive it by:
var jsonData = JSON.parse(responseBody);
postman.setGlobalVariable('token', jsonData.token);
This would go in your Tests tab, in order to execute this script after your request has been completed.
Now, a global variable token is set and can be accessed using {{token}} syntax in the following API requests you make.
I'll demonstrate it to you regarding the same, with a similar example:
1. Save the data of latitude and longitude into the global variables lat and long.
2. Reuse the data by referring to the name of the variable, i.e. lat and long by enclosing them within curly braces like {{lat}} and {{long}}.
You can also manage these global variables, by clicking on the gear icon in the top right corner, and selecting manage environments then opening the Globals tab.
Tip: You can also, save the request to obtain the token into your collections, so that each time, you don't have to craft the URL to obtain the token.
I am using postman to do some testing on a REST API.
To login I use a post request who respond with a token I need to keep to use it with another request.
I did it that way :
and then I want to use it in another request who need that token in the header :
I seems that it's not sending the token. What am I doing wrong ?
Let's say the login response is:
{
"message": {
"token":"Some token value here"
}
}
There is a slight change in the latest postman and here is the syntax to set variable:
var data = pm.response.json();
pm.environment.set("token", data.message.token);
Read here more information:
https://learning.getpostman.com/docs/postman/environments_and_globals/variables/
The problem was that I was using postman.setEnvironmentVariable() instead of postman.setGlobalVariable().
I found the answer here
I have used the below script in the Tests tab of the postman and it worked for me.
pm.environment.set("access_token", JSON.parse(responseBody).access_token);
After setting the access token in my first API, I am passing that access token in my second API.
You can save token to an environment variable and access in any requests under that collection. May be this link will be helpful:
Extracting data from responses and chaining requests
Go to Login API
Go to "Tests" tab.
Add folowing script. This script will set variable "AuthToken" with response token.
var jsonData = JSON.parse(responseBody);
postman.setEnvironmentVariable("AuthToken", jsonData.data.accessToken);
I'm trying to use the Survey API.
When I try and use the form online to request an Authorization token I get a
error message.
Invalid or missing access token" error message.
The form to test the API calls also asks for a Client Secret code but yet it auto fills the box with the API Key.
Any help here would be nice.
I'm not sure if this is a bug on Survey Monkey's end either in the API or the form that tests the API.
You should have received a reply to this via email but I wanted to ensure this was answered here in case anyone else is having the same issue.
There was a bug on our API console preventing an access token being issued, this is now fixed.
The access token has to be copied into the "Authorization" parameter in the format "bearer ". e.g. if your access token is 'fdhjfu3cc8ss=', make sure the Authorization parameter has "bearer fdhjfu3cc8ss=" in it (with no quotes). Note that you need to use the Access Token returned, not the Authorization Code.