Transcript
-
- So let's say that you're on some page here and you're unauthenticated and you go to log in. So here I have an account set up at test.com
-
with something as the password and we go to log in there. We're redirected back to a page, but it's not the exact same page that we were on previously. We were on some page,
-
but we got redirected back to this jumpstart page. In most cases, what would be ideal for our users is to take them back to the same page that they were on before they logged in so that they can continue
-
whatever it is that they were trying to do. And there are several different ways that you can actually go about this, but the approach that I like to take is to use the requests refer as a forward path
-
from the page that we're actually going to be redirecting from. So for us, that's going to be our login or register page. We're just gonna focus on the login flow here as register would be the exact same.
-
And what we can do is define a variable up here at the top of our file, or you can even do this inside of the controller called at let forward equals, and we can grab this directly off of the request.
-
So request, this will be header, and we can reach through to the refer. AdonisJS provides refer as both the correct spelling and the one defined in the spec there.
-
Then with that, what we can do is set this as a hidden input. So input type hidden, give it a name of forward so that it goes up with our forms payload there
-
and set the value to our forward value. Set that to an empty string there if we do not have a refer come through with our request. If they come straight to this page
-
or they have the no refer associated with the request, then the request will either be empty or obfuscated from us. So we won't always have a forward header to rely on.
-
So we can set that to an empty string in those instances. Now we're not quite done yet, but I wanna inspect exactly why we're not done. So let's jump back into our browser here.
-
We're on some page, I'm unauthenticated. So let's go into our login and let's fill our form out. So test@test.com, and I'm gonna type something invalid in as the password.
-
Before we submit this though, let's right click and inspect and check out our hidden forward value. So right now it's set to some page correctly.
-
Let's go ahead and log in though. We get redirected back here because I provided invalid user credentials. Let's go ahead and inspect that hidden forward field now,
-
and you'll see that it's now set to slash login rather than slash some page. What we wanna do is persist that previous forward URL
-
rather than resetting it to the login page after we have an invalid submission attempt. And thankfully, Adonis Chance provides those to us via flash messaging.
-
It's the exact same way that we already have our email pre-populated here from the previous submission value, and then the password's being obfuscated away from that for security reasons.
-
So if we jump back into our text editor here, what we can do is reach through to those flash messages to grab the old forward value to keep it with this new request.
-
And there's a utility for this called old. And all that we need to do is pass in the field name to this. So that's gonna be forward. So with that said, if we give this a save, jump back into our browser.
-
Let's go ahead and go back to our some page here to solidify that as our referrer. Go back into our login, and I send this off. So test@test.com. I'm gonna do something invalid there
-
as a password once more. Log in. Okay, we got redirected back with our invalid password. Let's check out our forward URL, and now it is still slash some page.
-
Exactly as we want it. Perfect. So we're done with the front end portion of this now. Let's go ahead and jump back into our text editor because we need to add the back end portion in.
-
So let's jump into our app directory, and let's start with our validator. So we'll go into our auth validator here. We're just focusing on login, so we'll get to login one. And we wanna add our forward field into this.
-
And I'm gonna set this as find string, optional. We don't wanna require a forward URL for those instances where it might be empty. And we also, or at least in my opinion,
-
you don't want to validate this as a URL either, because in the instance where the forward value provided to us is invalid, what I would prefer to do
-
is just to ignore its existence altogether, rather than return that back to the user saying, "Hey, the forward URL that's hidden from you is invalid."
-
So we'll omit the URL validation from that so that we can just ignore its value altogether if it is invalid. We'll do some manual validations here whenever we get to implement it.
-
So next, let's add in a service that would accept that string in. So let's right-click our services, and I'm just gonna call this requestService.ts,
-
export default request service. And we can add in a static getForwardURL that accepts in our forward string. And you know what?
-
We can also make that optional as well. I always do this. I forget to specify this as a class there. So if we do not have a forward value,
-
then we can just go ahead and return null as an explicit value there. Otherwise, we can try to parse this as a valid URL. So const URL equals new
-
and pass it through to the URL constructor as forward there. If an invalid URL is passed into this forward constructor, it's going to throw an error,
-
in which case we can catch that so that it gracefully handles it for our user. We can go ahead and just return null. Once we have a URL and we verified that it's valid
-
by passing it into the URL constructor, we can attempt to match it against a route defined within our application. So for this, we can import AdonisJS's router from AdonisJS core services router.
-
And there's a match function that takes in the URL. And we're going to pass in the URL path name to that. The second argument that this accepts
-
is the HTTP method that we want to match against. So for us, that's going to be get since we are redirecting the user somewhere with this forward URL.
-
We don't want to redirect them to a post or put or patch or anything like that. So if a route match was found,
-
then we can go ahead and return the URL's path name plus, and then this is up to you, whether or not you want to keep it, the URL's query string. Otherwise we can let this fall out
-
and just return null altogether. So to walk through this again real quick, real simply, if we do not have a forward URL, we're just going to kick back null. Then inside of a try catch,
-
we're going to attempt to parse the forward URL as an actual URL to get an instance of that URL so that we can use it to pass through the path name to AdonisJS's route matcher.
-
And we're also going to limit that to just looking at get requests. If we got back a route match from our defined route definitions, then we're going to go ahead and use the URL's path name
-
and query string as the final forward URL that we'll use. Otherwise we'll kick back null and we'll ignore any exceptions or errors that are thrown
-
so that we can ignore the forward URL altogether and instead redirect back to a default location. So now within our auth login controller,
-
we'll want to make use of this. So after we've logged the user ran and flashed their message and everything, we can go ahead and do const forward equals request service
-
and import that and call our get forward URL. Since we have added forward into our validated data, it's now right there on our data as an optional string. So we can do data.forward
-
to pass that into our get forward URL call. And then if forward has a value, and in this case, that value is something that's actually matched against one of our defined route definitions.
-
And it's also a relative path rather than an absolute path. We can go ahead and return response redirect to path and pass the forward path in there.
-
So let's give that a save, jump back into our browser and let's give it a test run. So I'm going to go back here, refresh just to make sure we're set. We're on some page. I'm going to go back to login.
-
Let's do test@test.com, something there for the password, hit enter and beautiful. We're now redirected right back to some page rather than the jumpstart page.
-
If we were to log out, open up a new tab, go to localhost 3333/login. We should not currently have a referrer.
-
We can go ahead and verify that by inspecting real quick. And indeed our forward URL is empty. So let's try sending this with an empty forward URL.
-
So test@test.com, something, hit enter and cool. Our default still working okay. We're taken to the jumpstart URL. Now in the event that the forward URL
-
that we're providing is a relative URL, currently with how we have things, that's going to end up getting ignored because the URL matcher expects an absolute URL
-
unless it's provided a default base URL. And that comes through as the second argument. So this would look something like in our case, HTTP localhost 3333,
-
and that would get appended onto the forward URL if it's missing it. Since this is going to be different between localhost and production, what we can do is pass that into an environment variable.
-
So let's dig into our .emv. I've removed the SMTP here just because I have those set to mail trap. And let's add in one called app domain.
-
And set this equal to HTTP localhost. And then we can dynamically add in the port from the environment variable value by doing dollar sign
-
and then curly braces with the port value in there. And now whatever port gets assigned to our server at runtime, if 3333 is consumed already,
-
then that will get injected in here to our app domain. Awesome. So let's go and jump back into our request service and swap out this hard-coded string now with our .emv,
-
import that from start .emv, get. And we don't have this coming through via our autocomplete at the moment because we next need to define that
-
within our start .emv.ts. So within here, just gonna add this with the other app key as app domain, .env, schema. And I'm gonna set this as just a string
-
due to how we have that port being added in there. Go back to our request service now and via our autocomplete, we should see our app domain inside of our environment variables.
-
Perfect. So with that saved, we now have support for relative URLs as well. So jumping back into our browser and if we're on some page, go into our login.
-
What I'm gonna do is mutate the forward value that we have here. So I'm just gonna take the localhost 3333 off so that we just have /somepage.
-
If we do test@test.com and enter our password in, hit enter to submit. Perfect. Now our relative URL is redirecting us back to some page correctly.
-
So awesome. Now we're able to forward our user back to where they were after login using a valid matched route inside of our application.
How To Redirect Back to the Previous Page After Login with AdonisJS
We'll learn an easy way we can safely redirect our user's back to their original page after they login or register in an AdonisJS application. We'll also verify the URL matches an actual GET route definition within our application.
- Created by
- @tomgobich
- Published
Join the Discussion 0 comments
Be the first to comment!