Stateless RESTful API and 3rd party authentication

2020-06-03 08:07发布

问题:

I want to use 3rd party authentication (OpenID, maybe OAuth but I guess OAuth is meant for authorization) so that user can login easily.

But does authenticating on every request means I call the 3rd party (eg. Google) many times even if I don't need any thing from it? For example, I use OpenID authentication but the API I use is something internal (eg. /api/tasks/add).

回答1:

Let's fix understanding issues first. OpenID and OAuth are a bit different. There is a simple way to memorize that different:

  • OpenID is for humans. Simple example: you want to skip boring registration step and let user reuse existing account.
  • OAuth is for services/robots. Simple example: you want your script to access external API with some user's data.

There is a simple explanation provided by wikipedia:

Note that with OpenID, the process starts with the application asking the user for their identity (typically an openid URI), whereas in the case of OAuth, the application directly requests a limited access OAuth Token (valet key) to access the APIs (enter the house) on user's behalf. If the user can grant that access, the application can retrieve the unique identifier for establishing the profile (identity) using the APIs.

So I want to use 3rd party authentication ... that user can login easily. would probably mean you are going to use OpenID.

Answering your question: you do not need to call any third-party services on any request. It will be very inefficient and slow. OpenID provider will return user's credentials and you are good to go.

Please make sure you have identified requirements correctly.



回答2:

OpenID Connect is an authentication mechanism written on top of OAuth2. The client obtains a bearer token that it can send in an Authorization header with each request to the resource server.

This ID Token is a JWT, signed by the OpenID provider. A decoded token looks something like this:

  {
   "iss": "https://server.example.com",
   "sub": "24400320",
   "aud": "s6BhdRkqt3",
   "exp": 1311281970,
   "iat": 1311280970
  }

So it can be verified by the resource server without needing to contact the OpenID provider. The OpenID provider has a User endpoint where the relying party can fetch more detailed user info that is not included in the token, such as name and email address.



回答3:

I believe both the answers by Renat Gilmanov and flup should be useful to you, but I will try to just answer the question that was asked, here.

No, it does not mean you contact the 3rd party site on every request. In fact, you can't, since the whole OpenID process should just happen once for a given session (it's a somewhat annoying manual step for the user)

I'll refer to the OpenID provider (3rd party) as Google, since that's the example you gave in the question. The only thing that Authentication will do for you is give you Google's assurance that the person making that particular request also knows the password to the Google account name they gave you.

After that, it's up to you to keep track of requests coming from the same "person" and treating them as the same account. Basically, however you're handling the rest of the user's "session" information, you can now assume that all requests in this session are from that user.

The most common way would be through passing a cookie to the browser immediately, which contains some identifier that you keep track of on the server, and that confirms for you that whoever passes you that cookie is also the person who knew the password for that Google account. Another option would be sending custom HTTP headers, which is preferable in certain ways, but trickier to do by hand.

You could build all of this manually, but I would very strongly recommend finding some library code to take care of as much of this for you as possible. You don't mention what you're using to build this Web Application (in fact, you don't explicitly say it's a web application, I just gleaned that from the way the question is tagged), but there are plenty of choices for pretty much every framework or system you're likely to be using.

On some level, everything I wrote applies if you're writing an API for a native mobile app to connect to, as well. But you may have to jump through some slightly more complicated hoops in order to have the user authenticate, since some OpenID providers assume you're coming through a web browser.