JWT-Authentication of mulitple Laravel-APIs with the same token - laravel

I have a laravel / angular app secured with tymon/jwt-auth.
Now I need a seperate Laravel (or Lumen) API. I want this API to accept the same tokens as the first one. I assumed that this would work if I would set the same secret and mount the middleware.
It doesn't. Using a freshly generated token I can query the first API but not the new one. Why is that? Is something else besides the secret used to verify the token?
What would be a good way to make this work? I would not mind to make a completely new authentication.
Edit: So it seems like a connection to the database is need to verify the token. Maybe it checks if the user specified in the token is actually present in the DB?
Edit2: Tore Nestenius commented about Aud-Claims. I wanted to go to the config/jwt.php file to check on that. But I had forgotten to create one. Now it works.

The aud claim in the token must match what both API's expect to see in the access token. I am glad my comment helped you to solve your issue.

Related

Cognito authorize endpoint in OAuth2 identity provider

been trying to figure this out forever, and I don't think it's supposed to be that complex...
I have an AzureAD setup with an OAuth2 Connection that I want to point to Cognito so that I can authenticate users in the User Pool, get a token back and call AppSync APIs, etc. Important note here, I cannot use Amplify in the current situation.
I have configured my App Client as follows:
The ngrok URLs are because I'm working on a cloud based app that needs tunneling. I have multiple URLs in there in the hope that I'd get one that works, to no avail.
To configure the OAuth2 Connection in Azure, I'm asked for 3 URLs,
authorize, token and refresh.
Here are the values I put into these fields
When I initiate the auth process with this connection, I get the redirect_mismatch error. I have no idea why. When I open the HostedUI, it shows up just fine, but it points to login instead of authorize. The redirect_uri, however, is localhost:3000/ as seen at the end of the address bar.
Clearly, I'm missing something, but I have no idea what. Should there be additional parameters in the config of my URLs on Azure's side? Anyone ever connected the two in this way? The company insists on this flow, and I just can't wrap my head around it.
Any and all help apreciated, thank you.
NOTE: There is a possibility to configure a custom OAuth2 connection on the side of Azure with more parameters, should this be the way? I do not, however, know what to put in these extra fields.
In the case of a Bot authentication, as it is the case in my situation, in Callback URLs, add the following:
https://token.botframework.com/.auth/web/redirect
This allows to open the authentication window when authenticating your bot.

[TOKEN_INVALID]: An invalid token was provided

I'm trying to host a discord bot on Heroku.
When it starts I get this error:
"UnhandledPromiseRejectionWarning: Error [TOKEN_INVALID]: An invalid token was provided".
But here is the weird part. It worked fine when I tested it first in Visual Studio Code. So in the process of me getting the files into Heroku, it got invalid.
Does anyone have a clue of how I can fix this?
Thx for any replies in advance.
Deploying app on heroku you have to change you client.login(token) to client.login(process.env.token) and add token to
as token - key and value - token copied from discord developers portal, remember (important note!) letters has to be the same, I mean, if you use capitals in process.env.TOKEN, the config var has to be now TOKEN.
I run into a similar problem, i encrypted the token so that i could store the encrypted token on heroku and decrypt it in the js to pass the actual token to the login method.
The weird part is, if i write the token directly as string into the js file or i use heroku and store it directly there, then it works. But if i store the encrypted token in heroku and decrypt it (and yes it is correctly decrypted) and give the decrypted token to the login method then it does not work.
I dunno if heroku make some weird stuff or discord.js doesnt support something i dont know...
So, what definitly works is:
You insert the token (client secret) on herokus config vars (settings from your dyno), then you use process.env.BOT_TOKEN and pass it to your Discord.Client().login().
I assume in your case its bot.login(process.env.BOT_TOKEN).
So for me it looks like the value i store in heruko and the value i send to discord must be the same...
You should enter a valid Discord bot token. You can obtain it by going to the Discord Developer Portal, then "Applications", select your bot, then go to "Bot" and click "Copy" under the token (it says click here to reveal).
I also encountered this situation.
I discovered that when using dotenv to read data from a .env file (Run on my computer), the names are not case sensitive. (could be wrong)
For example, TOKEN will be able to be treated as token, meaning when process.env.token can be returned with the value of TOKEN in the .env
file
But when I run on Heroku, what I just said will be gone (process.env.token will not return the value of TOKEN, but the token). Try double-checking that the name matches and correct it.
Like you've said, you logged into your bot with bot.login('TOKEN', () => { console.log; }
but bot.login doesn't support callback functions.
What I mean by this is, instead of the code before, you change it to bot.login('TOKEN').

Laravel Airlock Token

Introduction/Background
I'm looking to enable token authentication for multiple microservices and users. Both applications and users are $user objects.
I need to be able to authenticate once (hence token) using an auth server on a subdomain. I then need to be able to pass around a token that can be managed (revoked/refreshed whatever) by the Auth server.
The microservices are Laravel based, so using Airlock makes sense. Airlock generates tokens easily using:
$token = $user->createToken(now())
However, I see no method to manually check the validity of these tokens... So I assumed they are available in the database.
Airlock suggests that the token be returned as follows:
$token->plainTextToken
This produces a token, as expected. To my understanding, this is a public facing token. It does not match the token in the personal_access_tokens table.
Lets call these PublicToken and PrivateToken.
The private token is actually located in:
$token->accessToken->token
I want to be able to manually switch between a PublicToken. I assume Airlock is doing some security here.. and I want to invoke these secure methods required to check a PublicToken against the PrivateToken.
Please do not say "it's in middleware" ... The point is that I have multiple microservices and usertypes sharing a database. I have an auth server that will end up on secure architecture, and some of the other microservices wont be.... fundamentally I need to do a manual authentication because normal plug and play wont work. Using Airlock as the foundation is great. But I need to be able to know how to convert between public and private tokens.
Essentially I'm looking for the real version of the following psuedocode:
if( someTranslationFunction($public_token) == $private_token ) ...
TLDR: The problem
How do I validate a $token->plainText value against a $token manually?

How do we handle password change and password forgotten and token refresh?

This has been a really great set of tutorials at Thinkster.io. I've been able to take this approach to the backend and create a Vue front end to consume the API. However, how do we handle token refresh and password management? I wanted to make sure I haven't missed anything in https://thinkster.io/tutorials/django-json-api/authentication
Specifically, I'm looking for the following use cases:
When/how to refresh tokens
Update password - I'm guessing I can do that in the update serializer
Forgotten password - Should I tie this all the way back to the Django Auth reset?
Any suggestions on next steps would be great

Laravel Passport tokensExpireIn seems not working

i'm using Larave 5.4 passport to create SPA application. However, i was able to make authentication work. but access token are always short-lived tokens with 600s expiration time.
i could not increase expiration time with:
Passport::tokensExpireIn(Carbon::now()->addDays(15));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
it have no effect at all.
any help? thanks in advance.
Personal access tokens are always long-lived. Their lifetime is not modified when using the tokensExpireIn or refreshTokensExpireIn methods - as explained in Laravel's official documentation (https://laravel.com/docs/5.7/passport#personal-access-tokens).
The option of editing PassportServiceProvider.php in the vendor directory is a bad idea. Every time, you make an update (e.g composer update/install) or by another developer in production, code will be reverted to status quo, and it would start failing.
A better approach is to use Password Grant Tokens. The OAuth2 password grant allows your other first-party clients, such as a mobile application, to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire OAuth2 authorization code redirect flow. Be sure that you have duly installed passport (See Guide: https://laravel.com/docs/5.7/passport#installation), then run this command
php artisan passport:client --password
Having done this, you can request an access token by issuing a POST request to /oauth/token. Remember, this route is already registered by the Passport::routes method so there is no need to define it manually. If the request is successful, you will receive an access_token and refresh_token in the JSON response from the server. See payload sample below:
{
"grant_type" : "password",
"client_id":"your-client-id",
"client_secret":"your-client-secret",
"username":"twady77#gmail.com",
"password":"123456",
"scope":""
}
Sample response:
{
"token_type":"Bearer",
"expires_in":1296000,
"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjVkMWJjN2NhOTU0ZWU2YTZmOGNkMGEyOTFjOTI5YzU4Zjk3ODk3M2YxZDJmNjQ2NjkyZjhjODQyZjYxNTBjZGRiYzMwY2RjMzRmZjJhYmU1In0.eyJhdWQiOiI4IiwianRpIjoiNWQxYmM3Y2E5NTRlZTZhNmY4Y2QwYTI5MWM5MjljNThmOTc4OTczZjFkMmY2NDY2OTJmOGM4NDJmNjE1MGNkZGJjMzBjZGMzNGZmMmFiZTUiLCJpYXQiOjE1NDkyOTI5MjcsIm5iZiI6MTU0OTI5MjkyNywiZXhwIjoxNTUwNTg4OTI3LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.cSvu30xAT-boA5zmVuxTr0TfH_5MYuVWYi6NVQRbryZSswt8EAFTi5QXHH1f0O63DWnLA6VFBS2AfDe4-ryJZACDnt4gtPJOeuu1rNMZ53MU1vjxnyC8FsYz8v9vmYJsZPKqfTJpuJFYRFh7kkV7uWAmrEkuF3POnDn-GjW50f4i26lIZW5ta5j4nZQrIJCQUEzwXaQtn9H-qef3bTWAaplWaV-k7Blic-0TXXVfWa_CdoKCAzHROVBRWY1Idhe1LJkvGKldUGzUfliiB1x7EVVInq94VYEP5d9__90Z2UMUn5dCEgWkXvcEHYy87_4OSwu4TQk_f3hD82OVOEtJGgPyJqK51WqnQCBYwNtxNjqAW2oaMgpritp3G8nccUiyhkE4Pd_kj3cb2OvSNRXdDS9z-RnJb1OXUkja-4Xe_JfIWUjlTnkss18xMg89hcU_3xtBwUXBWHgffzcbNoI1oOwUL6Whekduiy8csf665v0cnzkPXISmvyGhiMseIlBEN9m9uESaJqD_g7WzbsEs7meI0CAF3230UgrI1MdYSAJMW0mMPF9EScH31a_Qpde5O233Ty6-S4NAp323Wneqs_jpGSfw81CvoI1JeY0hZccRC-MBBsQ2Ox7AM36H5L3p-ybricmT3oCcHEqhufq-ygyfqk1RufJwwRblwYPyaJE",
"refresh_token":"def50200c6b2378110190ac28d9d55f622885bb0b470a20543a6f1eefb18ed93c57b7040dc4db9444aa8853209bde9d5443a407d43fcaf1deb2e1f3f5ea3ce7431c4ec5e111bdc0cc71ca76034cd2a884441c51e4c922dddfa3f6e3a3fa8e1fbb8efe4581ce70d76590e732b3fa8b0c41a8abff4a8759f9dd1cc3ae46134fb67a8f25cd79e3229f6ee3238701ebfe0e8b0e2f14bd13c7fde3f813708a3de9928c8e992850994ca97bf61984cdb846bd0d72916312d9985472fc4293a3b3f2c55e1ef19621ef009623a6780f800ece9c8d835871dc795fda5daa43ac3fdae467e66b46e4eb73d53b8cb821522ee60979711c28c54fb2085f6000ac7e96e019ce51b9f92ea3fa2028aa0238fc3dca9c900e8dd77907782b22482f95a5e55708e5bda8c28f3732ff55e361f08447b33fe05d5646cecfb9faed462d327efdcc2a3742f46f9f825275d296b4ced25c05f3b6add68f43a2b448e4523d5410c631dc45bba"
}
Try to use this library: https://github.com/GeneaLabs/laravel-caffeine , and you can look laravel session config options
tokenExpireIn() instead of refreshTokensExpireIn() use then solve tokenExpireIn problem.
for passport grant token
Passport::tokensExpireIn(Carbon::now()->addDays(10));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(15));
This is only adding 10 minutes of expiry time. Don't know how and why, but instead changing internal codes. I Changed
Passport::tokensExpireIn(Carbon::now()->addDays(10000));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(12000));
Now it's adding 7 days of expiry time. Seems like addDays function adding 10000 minutes.
I have the same issue before for my application, I spent two days try to find what is the problem, The best solution that I came up with is to change the expire date directly in the PassportServiceProvider
Go to vendor/laravel/passport/src/PassportServiceProvider.php line 108
new PersonalAccessGrant, new DateInterval('P1Y')
for example to set the expire date to one week
new PersonalAccessGrant, new DateInterval('P1W')
I know this is a bad solution for fixing the issue, recently I have found the same issue on Laravel Git repo
https://github.com/laravel/passport/issues/47

Resources