SohoHouse / nuxt-oauth

Simple OAuth2 integration for your Nuxt app
MIT License
122 stars 27 forks source link

Dynamic resp. programmatic oauthHost #18

Closed col-panic closed 6 years ago

col-panic commented 6 years ago

Is it possible to dynamically set the oauthHost to authenticate against? I want to be able to leave the selection to the user (e.g. by providing a parameter on the url like http://test.me?oauthHost=https://myServer.at)

thanks

col-panic commented 6 years ago

Thanks a lot. But I'm not sure on how to perform the following now:

I have the oAuthHost variable stored in the vuex store. is there any way to fetch the value from there? Would it be a possible solution to provide a login(options) method?

samtgarson commented 6 years ago

@col-panic that sounds like quite a specific use case—I think having access to req would be enough for most cases.

I'm also not how to allow access to the Vuex store as all of this occurs on the server before Nuxt or Vue have been instantiated.

Feel free to fork this, I guess, I'd be happy to help if you get stuck.

col-panic commented 6 years ago

Maybe the following could be easily done:

So in my application I only would have to bind to vuex.oauth.host and modify this value in order for your module to pick it up.

Do you think this is feasible? Thanks!

samtgarson commented 6 years ago

The issue is that at the point the module needs to get the oAuthHost, the vuex store hasn't been instantiated yet—this all happens on the server before Nuxt has even been booted.

TBH I'm not sure this is feasible. Vuex seems like a strange place to store environmental configuration like the OAuth host. I'd recommend finding somewhere else to store it that is accessible from the server.

col-panic commented 6 years ago

I think I found a solution. I am extending the login$() function to support a parameter like this

$login('/targetPage&oauthHost=https://alternativeOauthHost.at')

Now if server-middleware.js# parses this login route, and finds out that there is an oauthHost defined, which is not equal to the one provided in nuxt.config.js it instantiates a new Handler providing this alternate oauthHost option for further operation.

Additionally I add the host to the vuex store.

I am not really interested in a fork. If I provide a proper patch, would you consider to merge it?

samtgarson commented 6 years ago

@col-panic allowing the oauth host to be set from the client side seems quite odd to me and opens up surface area for potential security threats.

However, if you'd like to do this you can without any changes—provide oauthHost as a function which receives req, and you can extract the oauthHost from the URL in the req object.

col-panic commented 6 years ago

What security threats do you see there? A rogue oauth server is not able to generate an access token that will be accepted by the resource server (as long as the resource server is not also bound to the rogue oauth server) I am about to access.

In my use case I write an administration app for a resource server that hosts its own oauth server. So I just need to bind it to a specific server with all my services. Even if the 2 would be different, and someone would bind the openid from server A while accessing the services from server B. This will not work, as it will not accept the token.

So I think that providing support for switching the oauth server should not be problematic.

samtgarson commented 6 years ago

Can you not achieve this in the way I described previously? e.g.

oauth: {
  oauthHost: req => extractHostFromURL(req.url)
}
col-panic commented 6 years ago

Unfortunately I do not have a connection to the vue instance from there (nuxt.config.js), thus I am not able to use the value provided (the targeted oauth host) e.g. via an input field. I tried to find a way to access the vuex store, and bind the input field to it, but failed. So I reverted to a solution calling $login() with additional parameters.

samtgarson commented 6 years ago

Sure, but if you visit the login route (/auth/login) with the extra parameter, does that not give you access to it in the request object? $login) is just a convenience method for redirecting to that route

col-panic commented 6 years ago

yes! I am currently working on a patch that will show you my approach - I will link it as soon as its ready! Thanks a lot for all your feedback :)

col-panic commented 6 years ago

You can see the approach at https://github.com/col-panic/nuxt-oauth/commit/477c2ea05919b0753b45026c5c25523a77b03902

I use it within a vue page like this

<template lang="pug">
    div 
        p {{this.$store.state}}
        p {{this.$store.state.swaggerClient}}
        input.form-control(name="url" placeholder="server url" type="url" v-model="connectionUrl")
        button(@click="oauthDynamicLogin()") Connect
        button(@click="$logout()") Disconnect
</template>

<script>
export default {
  computed: {
    connectionUrl: {
      get() {
        return this.$store.state.connectionUrl;
      },
      set(value) {
        this.$store.commit("SET_CONNECTION_URL", value);
      }
    }
  },
  methods: {
    oauthDynamicLogin: function() {
      var value = "/connection&oauthHost=" + this.$store.state.connectionUrl;
      this.$login(value);
    }
  }
};
</script>

(This is not final, just to demonstrate)

samtgarson commented 6 years ago

I understand the concept, but I believe (as I mentioned before) you can achieve this without any changes to the library. Have you tried the approach I noted above?