# How to use ESA or ESAT to authenticate against custom provider

**URL:** https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142
**Category:** Design
**Created:** [January 17, 2018, 4:30pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142 "2018-01-17T16:30:27Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![belgoros](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/belgoros/32/16101_2.png) [@belgoros](https://discuss.emberjs.com/u/belgoros)
#### Post date: [January 17, 2018, 4:30pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/1 "2018-01-17T16:30:27Z")

</div>

I can’t find any resources on how to proceed and is it possible to use ESA ( **ember-simple-ath** ) or ember- **simple-auth-token** add-on if I have to authenticate a User agains a custom external API provider ? I mean that every User (if not authenticated) should be redirected to the custom authentication portal login page, enter user name and password and which will send back a token (JWT). This authentication API has my application registered, redirect URL (callback) and provided me with a secret key and client ID. A successful response from that API after authentication would be like that:

`http://redirect_url:port/#access_token=eyJhbGciOiJSUzI1Ni.`

I have already read Part 1 and [Part 2](https://emberigniter.com/real-world-authentication-with-ember-simple-auth/), took a look at [Ember JS with Rails](https://medium.com/@coorasse/rails-ember-google-oauth2-807e24c3266) article but still have no answer for the question. Any suggestions, advices and links would be helpful !

---

<div class="post-metadata">

### Author: ![dknutsen](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/dknutsen/32/16471_2.png) [@dknutsen](https://discuss.emberjs.com/u/dknutsen)
#### Post date: [January 17, 2018, 4:58pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/2 "2018-01-17T16:58:47Z")

</div>

Hey @belgoros, does your authentication API use a standard OAuth flow? It seems like it would best fit the Implicit Grant Flow, and ESA now has an implicit grant authenticator built-in. We use the Implicit Grant authenticator in our apps much in the same way you describe. The ‘dummy’ app in ESA has example of each authenticator, and the ESA docs should help you get started, and I’m pretty familiar with that code (I actually worked on the PR for the implicit grant support) so feel free to ask any questions in this thread.

First, do you have any non-protected routes? That is do you have a landing page of any kind for unauthenticated users, or do you want any user that hits your app who isn’t authenticated to be redirected to the login? We actually use the latter approach in our app and it makes the implicit grant flow slightly more complicated, but still pretty simple to set up with ESA.

At a high level you’ll want to:

- set up an authenticator (which extends ESA implicit grant authenticator),
- set up an authorizer (which extends ESA OAuth2 Bearer authorizer)
- set up a session store (standard ESA store of your choosing)
- setup a callback route (we call ours ‘callback’) which extends the ESA implicit grant callback route mixin
- If you have a landing page, make some sort of button/action that redirects the user to your API login page, if you don’t and all your routes are protected, you’ll need to add some custom code to your callback route (I can help you with that if you need it)
- make sure you have your `authenticationRoute` [set up correctly](https://github.com/simplabs/ember-simple-auth/pull/985#issuecomment-314817585) so it forwards all unauthenticated visitors to either the landing page or the callback route

Anyway, hope that’s helpful. Good luck!

---

<div class="post-metadata">

### Author: ![belgoros](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/belgoros/32/16101_2.png) [@belgoros](https://discuss.emberjs.com/u/belgoros)
#### Post date: [January 17, 2018, 7:32pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/3 "2018-01-17T19:32:30Z")

</div>

Hi, Dan ! Thanks a lot for your response, really helpful. So my idea was to use Ember JS in front-end and Rails API as backend solution. There no non-protected routes, what means that every User trying to access the application should be first of all authenticated via a corporate API end-point, e.g. `https://our.copmany.com/authorization/auth`, - so a common company login page will be displayed where a User should enter his username and password. Once a User is authenticated, a corporate OAuth API redirects him to the URL registered as redirect URL (or callback) for the requesting application and assign a JWT token like that:`http://redirect.url.com/#access_token=eyJhbGciO`. This is how they see every User should enter an application. I feel really lost between `oath2, omniauth, omniauth-omniauth2, doorkeeper` (Rails side) and the previously cited Ember solutions. I’ll take a look at the dummy app in ESA repo and come back with other questions if I have some. Thank you once again.

---

<div class="post-metadata">

### Author: ![dknutsen](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/dknutsen/32/16471_2.png) [@dknutsen](https://discuss.emberjs.com/u/dknutsen)
#### Post date: [January 17, 2018, 7:41pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/4 "2018-01-17T19:41:48Z")

</div>

Yeah unfortunately I can’t really help with the Rails side but that sounds pretty much exactly like how our app functions, and we use a pretty spec-compliant version of the OAuth 2 implicit grant flow. So on the Ember side I’d definitely recommend using the ESA implicit grant support and I can help you with the specifics of that for sure, feel free to post questions in this thread!

---

<div class="post-metadata">

### Author: ![dknutsen](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/dknutsen/32/16471_2.png) [@dknutsen](https://discuss.emberjs.com/u/dknutsen)
#### Post date: [January 17, 2018, 8:19pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/5 "2018-01-17T20:19:10Z")

</div>

Here’s basically all of our authentication code, should be pretty much in line with what you want to do.

### Install Ember Simple Auth

First install ember-simple-auth. Obvious first step. `ember install ember-simple-auth`

### Create a callback route (we called ours ‘callback’)

This is the route your API will redirect the users browser to once authentication has been completed. From here the ESA implicit grant mixin will process your access token and then it can forward you on to the original desired URL, or to a default ‘routeAfterAuthentication’

`ember g route <route-name>`

### Create authenticated route mixin

Next create a mixin in your project called ‘authenticated-route-mixin’ which extends the ESA authenticated-route-mixin with your authenticationRoute (and other) settings:

```auto
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';

import ENV from '../config/environment';

export default Ember.Mixin.create(AuthenticatedRouteMixin, {
  // NOTE: this used to be something we could set in config/environment.js but
  // that usage was removed in ESA recently and now it must be set
  // individually on all routes that extend AuthenticatedRouteMixin, so
  // instead of duplicating that prop in every single one of our routes
  // I am extending the ESA mixin with our own (of the same name) and
  // adding the authenticationRoute property here.
  //
  // (see https://github.com/simplabs/ember-simple-auth/pull/985)

  // these can either be static strings or computed properties (they are CPs
  // in the base ESA mixin which we're extending)

  authenticationRoute: 'callback', // use the route you generated above

  //routeAfterAuthentication: '',

  //routeIfAlreadyAuthenticated: '',
});

```

### Extend the mixin you just created in your routes

In all your protected routes you should extend the mixin that you just created locally (which itself extends ESA’s) instead of extending ESA’s directly. This will allow you to set the `authenticationRoute` property once instead of having to do it on all of your routes.

e.g.:

```auto
import Ember from 'ember';
import AuthenticatedRouteMixin from "<project-name>/mixins/authenticated-route-mixin";

export default Ember.Route.extend(AuthenticatedRouteMixin, {
  ...
});

```

### Create authorizer

Create a file called `<project-root>/authorizers/application.js` and put the following in it (unless you want a different authorizer):

```auto
import OAuth2Bearer from 'ember-simple-auth/authorizers/oauth2-bearer';

export default OAuth2Bearer.extend();

```

### Create an authenticator

Create an authenticator, ours is in `<project-root>/authenticators/oauth2.js` and extend the ESA implicit grant authenticator, and set your token endpoint:

```auto
import ENV from '../config/environment';
import OAuth2ImplicitGrant from 'ember-simple-auth/authenticators/oauth2-implicit-grant';

export default OAuth2ImplicitGrant.extend({/* any customization here, we have none */});

```

### [optional] Define a session store

We just use the default adaptive store but if you want a custom one follow the [README](https://github.com/simplabs/ember-simple-auth#session-stores) to define one

### Add some magic to your callback route

Since you don’t want a landing page and all your routes will be protected you’ll want to add some magic to your callback route so you can use it on both ends of the authentication process. Our callback route looks like this, you may need to change a couple of the specifics of the original authentication URL to fit your backend:

```auto
import Ember from 'ember';
import CallbackRouteMixin from 'ember-simple-auth/mixins/oauth2-implicit-grant-callback-route-mixin';

import ENV from '../config/environment';

export default Ember.Route.extend(CallbackRouteMixin, {
  routeOnError: 'index',
  authenticator: 'authenticator:oauth2',

  generateAuthUrl: function(authHost, redirectHost, redirectHash) {
    let redirect_uri = redirectHost + encodeURIComponent("/#/callback");
    let client_id = ENV.APP.OAUTH_CLIENT_ID;
    let response_type = "token id_token"; // this is what we use, YMMV
    return `${authHost}/oauth/authorize?client_id=${client_id}&response_type=${response_type}&redirect_uri=${redirect_uri}&scope=openid&state=${redirectHash}`;
  },

  activate(){
    this._super();
    // if we don't have an access token, it means we're not authenticated and we should redirect the user to the API login page
    if(window.location.hash.indexOf('access_token') === -1) {
      let redirectHost = window.location.origin; // hostname of the URL we're on
      let redirectHash = encodeURIComponent(window.location.hash.slice(1).split('?')[0]); // our hash location aka our ember route
      if(redirectHash === "") {
        redirectHash = "/";
      }
      // generate an auth url which is our API server and where we want the API to redirect us back to
      let authUrl = this.generateAuthUrl(ENV.APP.OAUTH_HOST, redirectHost, redirectHash);
      // make the redirect
      window.location.replace(authUrl);
    } 
  },
});

```

Basically the way it works is:

- a user will hit your app, but they are unauthenticated, so ESA realizes this and forwards the app to your `authenticationRoute` which you defined in your mixin above and is in this case the name of your callback route (again we just called it ‘callback’)
- Once Ember gets here (the activate method of your callback route) it will see that there is no access token in the hash, so it will construct the authentication url and redirect to it, sending the user’s browser to your API login page with params specifying redirect\_uri, etc
- The user logs in, and once that happens the API forwards them back to the redirect\_uri which you provided the API with on the way in, it includes the access\_token in the hash params. Since you put your callback route in as the redirect\_uri, you will be forwarded right back to your callback route, but this time you have the access\_token in your hash params so ESA takes over and processes everything as a normal implicit grant flow

Anyway hope all this is helpful and again feel free to post questions here once you get that far

---

<div class="post-metadata">

### Author: ![belgoros](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/belgoros/32/16101_2.png) [@belgoros](https://discuss.emberjs.com/u/belgoros)
#### Post date: [January 17, 2018, 8:27pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/6 "2018-01-17T20:27:09Z")

</div>

Reaaaaally helpful, Dan, thank you very much ! It took me almost one week before I got such a clear explanation the way Ember will work ! It is getting more and more clear. Just super !

---

<div class="post-metadata">

### Author: ![belgoros](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/belgoros/32/16101_2.png) [@belgoros](https://discuss.emberjs.com/u/belgoros)
#### Post date: [January 17, 2018, 9:53pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/7 "2018-01-17T21:53:35Z")

</div>

Dan, I followed your guide lines and created a [repo](https://github.com/belgoros/ember-esa) at GitHub. I can’t figure out:

- how and when `generateAuthUrl` function is called and how we pass in the parameters ? This is where I should put my authentication provider URL ? As far as I understood, it is `generateAuthUrl`that should return a complete URL to query to get the login window ?
- do the other functions come from `CallbackRouteMixin`(like `encodeURIComponent`, for example) ?

Regards

---

<div class="post-metadata">

### Author: ![dknutsen](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/dknutsen/32/16471_2.png) [@dknutsen](https://discuss.emberjs.com/u/dknutsen)
#### Post date: [January 17, 2018, 10:46pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/8 "2018-01-17T22:46:36Z")

</div>

In answer to your questions:

- generateAuthUrl is called [here](https://github.com/belgoros/ember-esa/blob/master/app/routes/dashboard.js#L26) in the activate hook of the callback route. it’s not actually necessary to do it in a separate function like that (you could do it all in the activate hook), that was kind of an arbitrary decision on our part. As for the params… redirectHost and redirectHash are just grabbed from the browser URL and then ENV.APP.OAUTH\_HOST is something you’ll have to define in your config/environment.js file (more on that below). EDIT: the activate hook is called whenever a route is “entered” or “activated”, so when ESA decides your user is unauthenticated, it forwards them to the `authenticationRoute` you defined, which in this case should be your callback route) and then the “activate” hook is the first thing called.
- encodeURIComponent is a built in javascript function. The CallbackRouteMixin provides mainly some methods for extracting the auth\_token from the hash params and shoving them into your ESA authenticator/store, but you don’t need to worry about all that unless you need to customize it

I noticed you called your callback route ‘dashboard’, and I’m assuming ‘dashboard’ is a route you actually want to use to fetch and render data. I would actually recommend silo-ing all of your auth related code in a separate route (and I’d actually recommend the route name ‘callback’ like we have it in our app, it’s clearer what it’s meant). All we have in our “calback” template is an outlet, and we probably don’t even need a template at all, nothing is ever rendered there. Essentially the callback route is the exit and entry point for our app, so an unauthenticated user forwards to callback route, which forwards to the API for auth, which forwards back to the callback route, which then forwards us on to the main app route (once authentication is completed by the CallbackRouteMixin, but that part should be transparent to you).

Secondly, to use the code exactly as we are you’ll want to define two vars in your config/environment.js file:

- `ENV.APP.OAUTH_HOST = "https://our.company.com";`
- `ENV.APP.OAUTH_CLIENT_ID = "<client id>";`

The host is just the URL for your API (and you could adapt the code to have your full path e.g. `https://our.company.com/authorization/auth`) and the client id is… well… your client id

---

<div class="post-metadata">

### Author: ![belgoros](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/belgoros/32/16101_2.png) [@belgoros](https://discuss.emberjs.com/u/belgoros)
#### Post date: [January 18, 2018, 9:25am UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/9 "2018-01-18T09:25:57Z")

</div>

Thank you, Dan. I’ve [updated](https://github.com/belgoros/ember-esa) the app by renaming `dashboard` route to `callback`. The questions I have now:

- what URL should I access to trigger the authentication call ?
- Should I setup `callback` route as root like that in `app/router.js`:

```auto
this.route('callback', { path: '/' });

```

When I start `ember s` and go to `localhost:4200`, nothing happens. If I navigate to `localhost:4200/callback`, I have the below errors in Chrome console:

```auto
router.js:938 Error while processing route: callback Cannot read property 'then' of undefined TypeError: Cannot read property 'then' of undefined
    at Class.authenticate (http://localhost:4200/assets/vendor.js:131953:87)
    at Class.authenticate (http://localhost:4200/assets/vendor.js:132839:35)
    at Class.activate [as _super] (http://localhost:4200/assets/vendor.js:132580:27)
    at Class.activate (http://localhost:4200/assets/ember-esa.js:473:12)
    at Class.superWrapper [as activate] (http://localhost:4200/assets/vendor.js:56334:22)
    at Class.enter (http://localhost:4200/assets/vendor.js:42746:12)
    at callHook (http://localhost:4200/assets/vendor.js:61351:38)
    at _handlerEnteredOrUpdated (http://localhost:4200/assets/vendor.js:62936:9)
    at handlerEnteredOrUpdated (http://localhost:4200/assets/vendor.js:62958:7)
    at setupContexts (http://localhost:4200/assets/vendor.js:62913:9)

```

What did I miss again ?

---

<div class="post-metadata">

### Author: ![dknutsen](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/dknutsen/32/16471_2.png) [@dknutsen](https://discuss.emberjs.com/u/dknutsen)
#### Post date: [January 18, 2018, 3:22pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/10 "2018-01-18T15:22:37Z")

</div>

So the callback route is only used by Ember for authentication, it will never display anything, it will never have links to it, it’s basically a special login route. We didn’t specify a path for our callback route meaning the path would be the default `/callback`.

To trigger the auth call, you’ll need to have one or more other routes, like “dashboard” for example which can have the ‘/’ path. In the dashboard route you’ll want to extend the authenticated route mixin that you created above:

```auto
// routes/dashboard.js

import Ember from 'ember';
import AuthenticatedRouteMixin from "<project-name>/mixins/authenticated-route-mixin";

export default Ember.Route.extend(AuthenticatedRouteMixin, {
  ...
});

```

Doing this tells ember simple auth that you want this route (dashboard) to be protected (auth is required to access it). If a user visits it without being authenticated first ESA says “woah buddy you can’t do that” and forwards them to the `authenticationRoute`, which in your case should be `callback`. Then the callback route’s `activate` method will be triggered, which should send you on the redirect. Then any other routes you define (based on what you said earlier) should also be protected and therefore extend the mixin as well.

Anyway, your router should look something like this:

```auto
import Ember from 'ember';
import config from './config/environment';

const Router = Ember.Router.extend({
  location: config.locationType,
  rootURL: config.rootURL
});

Router.map(function() {
  // this is your authentication route that handles all of your authentication logic, both in and out
  this.route('callback');

  // this is your "home route" where you will want to actually render some stuff
  this.route('dashboard', { path: '/' });
});

```

---

<div class="post-metadata">

### Author: ![belgoros](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/belgoros/32/16101_2.png) [@belgoros](https://discuss.emberjs.com/u/belgoros)
#### Post date: [January 18, 2018, 7:29pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/11 "2018-01-18T19:29:46Z")

</div>

I [updated](https://github.com/belgoros/ember-esa) as you suggested. When reading your explications (thank you once again for your time), everything is clear, but in practice it does not work as expected. I supposed that after applying the above modifications, my dashboard will be protected and inaccessible, but it is not the case. I can access it (at `localhost:4200`) without any problems. What is wrong here ? Thank you.

---

<div class="post-metadata">

### Author: ![dknutsen](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/dknutsen/32/16471_2.png) [@dknutsen](https://discuss.emberjs.com/u/dknutsen)
#### Post date: [January 18, 2018, 7:56pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/12 "2018-01-18T19:56:32Z")

</div>

Looks like you copied [this line](https://github.com/belgoros/ember-esa/blob/master/app/mixins/authenticated-route-mixin.js#L2) wrong. Your custom authenticated route mixin should be importing and extending the authenticated route mixin from ESA, not from your own project. In essence yours was importing and extending itself (honestly not even sure how that didn’t bomb out) and so it never ran any of the ESA code. You should change that line from this:

```auto
import AuthenticatedRouteMixin from '../mixins/authenticated-route-mixin';

```

to this:

```auto
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';

```

Also it looks like you added some empty methods in the authenticator you defined, I’d take those out unless you plan to customize them later. Otherwise those will overwrite the ESA authenticator that you’re extending and do nothing.

---

<div class="post-metadata">

### Author: ![belgoros](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/belgoros/32/16101_2.png) [@belgoros](https://discuss.emberjs.com/u/belgoros)
#### Post date: [January 18, 2018, 8:43pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/13 "2018-01-18T20:43:44Z")

</div>

Yep, - f[ixed](https://github.com/belgoros/ember-esa/commit/3e002c730bd48f28a723b022253442dcf15e9360) it 🙂I also removed unused imports for Ember and ENV and commented out methods in `oauth.js`.

I’ll have to change the redirect URL registered in authentication API server, because it tried to redirect me to `https://my.copmany.com/oauth/authorize?client_id=my_client_id&response_type=token&redirect_uri=http://localhost:4200%2F%23%2Fcallback&scope=profile%20openid&state=/`

Should I always set it as `http://some.host/#/callback` as it was declared in `activate` function in `callback.js`:

```auto
let redirectHost = window.location.origin;

```

Is it a convention to always have `/#/callback`? Thank you !

---

<div class="post-metadata">

### Author: ![dknutsen](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/dknutsen/32/16471_2.png) [@dknutsen](https://discuss.emberjs.com/u/dknutsen)
#### Post date: [January 18, 2018, 8:51pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/14 "2018-01-18T20:51:52Z")

</div>

The reason you need to redirect from the API to the callback route is that the callback route is responsible for processing the access\_token, so when the API redirects it will include the access token, the callback route will process it, and then ESA decides what to do from there.

If you always wanted to redirect the user to the same route (like dashboard) after logging in, you could set that in the routeAfterAuthentication property in your AuthenticatedRouteMixin. If you wanted to redirect to whatever the user was originally trying to get to before the auth intercept you would need to do what we do and use the ‘state’ param (your server would have to support it as well).

---

<div class="post-metadata">

### Author: ![belgoros](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/belgoros/32/16101_2.png) [@belgoros](https://discuss.emberjs.com/u/belgoros)
#### Post date: [January 18, 2018, 9:16pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/15 "2018-01-18T21:16:16Z")

</div>

Ok almost got it :). I tried to register the client in [Google API Console](https://console.developers.google.com/), and it does not accept the redirect URL `http://localhost:4200/#/callback`.

```auto
Invalid Redirect: http://localhost:4200/#/callback cannot contain a fragment.

```

Could you tell me which redirect URL should I set up to play a little bit with this Ember client ? Thank you.

---

<div class="post-metadata">

### Author: ![dknutsen](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/dknutsen/32/16471_2.png) [@dknutsen](https://discuss.emberjs.com/u/dknutsen)
#### Post date: [January 18, 2018, 9:36pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/16 "2018-01-18T21:36:05Z")

</div>

That’s a little tougher to work around… you could try changing your location type from “hash” to “auto” which would make it `localhost:4200/callback` but other than that you’d probably have to change it to just ‘/’ instead of ‘/callback’ and then put something in the application route that intercepts anything with the #access\_token= and forwards it to the callback route

---

<div class="post-metadata">

### Author: ![belgoros](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/belgoros/32/16101_2.png) [@belgoros](https://discuss.emberjs.com/u/belgoros)
#### Post date: [January 19, 2018, 2:36pm UTC](https://discuss.emberjs.com/t/how-to-use-esa-or-esat-to-authenticate-against-custom-provider/14142/17 "2018-01-19T14:36:14Z")

</div>

So I’ll have to modify the following line in `callback.js`:

```auto
let redirect_uri = redirectHost + encodeURIComponent("/#/callback");

```

to

```auto
let redirect_uri = redirectHost + encodeURIComponent("/callback");

```

Then how should I change the following line:

```auto
let redirectHash = encodeURIComponent(window.location.hash.slice(1).split('?')[0]);

```

Doing so (I set up the `redirectHash = "/";` and `let redirect_uri = redirectHost + encodeURIComponent("/callback");`, I still git `404` error from Google APIs, where the `Authorised redirect URIs` was set to `http://localhost:4200/callback`.

Thank you
