Separate invalid token responses - laravel

Currently, if user tries to reset password using link which was built using reset token, at certain point validateReset function inside PasswordBroker.php is called. In the body of this function, validation of token itself is done, and if it is not valid static::INVALID_TOKEN will be returned. The problem is that from this response I can not know if the token was invalid because token string was wrong or because the token has expired.
My question is if it is possible to override this function to act differently for this two cases, specifically, I want to display informing message to user if token has expired and send him an email containing new reset link.

Related

Angular: await for query string parameter but do something else if it doesn't appear

I have tried to formulate a question title the most generic way that applies to my problem.
I have an Angular application where I have to handle authentication over an external requirement: either use a query string parameter token that has to be exchanged with the server for a JWT, or try to search for a JWT refresh token in the local storage.
It is:
First test the query string: if there is a queryString parameter token, grab the token, delete any JWT in the local storage, exchange the token via API for two JWTs (id_token and refresh_token)
Else go for the refresh token: if there is a refresh_token in the local storage available, exchange it for a JWT id_token via API
Else, if none of the two are available, the user is unauthenticated and a prompt should be displayed
I used Observables almost the correct way
this.queryParamMap$.unsubscribe();
this.queryParamMap$ = this.activatedRoute.queryParamMap
.subscribe(
params => {
let token = params.get('token');
........
if (!!token) {
doLoginWithToken();
else if (isJwtRefreshAvailable())
doLoginWithRefreshToken();
There is one problem with this approach: the very first time the application starts up, the query param map is empty, even if I follow a direct browser link http://localhost:4200?token=AAAAAAAA. I have to wait for the next element which contains the token.
This has two undesirable effects:
At the first attempt, being the token undefined, the application immediately tries to log in with the refresh token
If I filter the queryParamMap observable for a token being present, if a token is never present the observable will never emit, thus not activating the subscription.
My problem can be summarized/generalized as follows.
I have an Observable that I know for sure emits undefined the very first time, but either in no time it could be ready with a proper value, or it won't emit new values after the initial undefined.
Else said, while the observable emits undefined and my code starts reacting to it (e.g. by testing for token), a new value can be ready for emission right away.
How can I solve this in Rxjs? Note that accessing the JWT token from the local storage is a synchronous operation, but it's easy to create Observable.of(localStorage.get(KEY)) which emits immediately if a refresh token is present.
For that, I can't realistically use race operator, because the refresh token is always ready and always wins the race.
How can I write asynchronous code that performs like the steps I described earlier?
As the ultimate result of the authentication, an Observable<UserProfileDto | undefined> emits the information about the user, which is used to display personalized information.
You have 2 problems here:
On init you got "undefined" value (its because probably, under the hood, there is some BehaviourSubject emitting its default value). To overcome this, you can add RxJS operator (skip(1)) to skip that first value, but:
Problem here is if you do not have query values at all, you will not reach your subscribe function. Its because queryParamMap will emit a value only, if there is a change (and in that case there is not):
You can do it without Angular, to just parse url from:
const urlParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlParams.entries());
Or using router in Angular:
this.router.events
// Wait for the navigation end event (since component is initialized before angular router navigation is done)
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe((event: NavigationStart) => {
// Take query params snaphot
const map = this.route.snapshot.queryParams;
});

How does validation of JWT distinguish difference between token types?

I am playing around with building a custom Oauth2/OpenID library, and is having thoughts about validating the tokens.
I am using only JWT for all token types (Access, Refresh & ID), but I am thinking; How would the resource server validate ex. the access token, and make sure it is only access tokens from the issuer being accepted, and not refresh or ID tokens, since they would also be valid, hence they come from the same trusted issuer?
Likewise, how would make sure, the token sent with a refresh grant, is not just an valid access token, since it would also be verified...
I know an easy fix would be just making a custom claim, describing what kind of token it is, or using different signatures for each, but is there a "right" way of doing it?
One way to separate the ID token from the Access token is by looking at the typ claim in the JWT-header.
Some IdentityProviders uses the at+jwt typ to indicate that the token is an access token that follows certain rules. But this is not a mandatory thing to follow.
{
"typ":"at+JWT",
"alg":"RS256",
"kid":"RjEwOwOA"
}
Otherwise they can look at the claims inside the token to determine if it is an access or ID-token. The token-signature itself can't be used to determine the token type.
You can read more about the standard for access token here and here
Refresh and reference tokens are typically not in a JWT format, instead they are more like a random string.

WordPress is creating nonce as a logged in user but verifying it incorrectly

I'm having trouble validating a nonce created with wp_create_nonce() inside a hidden input with the name nonce in an html form:
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce('action_name'); ?>" />
The form submission is done via ajax and validated with check_ajax_referer('action_name','nonce'). This always returns -1. All REST endpoints have been tested without nonces and work 100% fine.
The issue seems to stem from wp's user identifcation.
My debugging so far
Nonce creation
Within wp-includes/pluggable.php wp_create_nonce('action_name') creates a nonce hashing various variables including the user id and the action.
Ajax call
I submit an ajax call which calls check_ajax_referer('action_name','nonce'). This in turn calls wp_verify_nonce($nonce,$action) which verifies the nonce by hashing the same variables and comparing the two.
Reverse engineering to locate problem
My problem is that wp_create_nonce('action_name') is being created with the correct user id. However, when I run check_ajax_referer('action_name','nonce') which calls wp_verify_nonce($nonce,$action) which in turn calls wp_get_current_user(); no user is found (user id is 0).
Evidence the problem is to do with user id
If I temporarily edit wp-includes/pluggable.php to force my user id, the nonce validation works fine. It's as if ajax requests to a known and valid endpoint are being treated as if the user is logged out regardless of whether they are or not.
I'm clearly missing something here, but I have no idea what.
This is happening because a separate nonce with the action wp_rest is not being sent by the server to the client and received back from the client in an HTTP request header called X-WP-Nonce with every REST request.
To get this working, you will have to generate a nonce like this:
wp_create_nonce('wp_rest')
...and provide it to the client making the rest call. Once your client has the nonce value, you need to add it to every REST request e.g.:
headers: {
'X-WP-Nonce': nonce,
}
Creating the nonce on the server and accessing it on the client can be done several ways. Using wp_localize_script() is the most common and probably best practice for WordPress. wp_localize_script() addds a global variable to the client for a script to access. See https://developer.wordpress.org/reference/functions/wp_localize_script/.

Laravel 5.2 TokenGuard implementation

How to use token guard to create API? I tried it to implement it and I am getting error
call_user_func_array() expects parameter 1 to be a valid callback,
class 'Illuminate\Auth\TokenGuard' does not have a method 'attempt'
After dig into the source code of laravel, I found that the token guard is useless for now. All auth are passed to auth middleware, from there, you can see that it called Auth::guard($name)->guest() to check whether the user is logged in. The \Auth::guard will get the proper guard that you specified in route. Let's say here is the TokenGuard. In \Illuminate\Auth\TokenGuard, check the user function to see how TokenGuard get a user. First, it will get the input parameter named api_token. Then it will let the provider which may be eloquent as the default configuration to search a value in the database. If any value is found, a new user instance is created. If there is not a input value named api_token, then some other choices will be tried:
bearerToken, which the Authorization HTTP header value that starts with: bearer.
password, which passed through HTTP header: PHP_AUTH_PW.
which key to match in the model is specified by the protected property storageKey.
So the token guard is used to implemented third-party API access token, not a temporary access token that is stored in the session.

make ajax parameters secure

I want to send email value in parameters in ajax. I am using following code it is working properly, but I want to make it secure. no user can check or pass invalid value from calling this action in query string or in any other way. How can I make it secure?
$.ajax({
url: '/Application/UserInfo/',
type: 'POST',
data:{email:emailid},
success: function (result) {
var json = eval(result);
}
});
If you dont want anyone to be able to see the value of the email parameter, you should consider using HTTPS.
But for passing invalid values, you should do some validation server side where this value is used
It may help if you are doing it with two steps at all:
First you can check the email having the right format with a regular expression:
/^\w[\w|\.\-\_]+#\w[\w\.\-äöüÄÖÜ]+\.[a-zA-Z]{2,18}$/.test(email);
Then you may crypt the mail and then you can send it safely.
I am using blowfish. On page loading I generate a key that is set to the javascript of my page. Both, javascript and php have a blowfish controler that can crypt and decrypt any value. I am crypting the value on javascript and send it to the server.
There I decrypt it and check it again with regular expression. The key is not sent to server again, its stored somewhere in the session or so.
To take care that the email is correct you can check whether the domain is reachable through curl or so, but I prefer sending a confirmation mail to the adress and wait for an accept with a generated unique token.
If you just want to get sure of a user signed in with google plus account you may get use of the google plus api and check if the user is logged in. If not you don't accept it.

Resources