New from the DevTools team: Stresseur, the AI test engineer for APIs →
DevTools
Back to Blog
A brass key beside a small hourglass on a dark desk

What Is OAuth 2.0? Testing Token Flows in YAML

Mustafa BayramogluMustafa Bayramoglu

OAuth 2.0 is an authorization framework that lets a third-party application get limited access to an HTTP service, either on behalf of a user or on its own behalf. It hands the application an access token instead of the user's password. Below you will find the roles, the tokens, the grant types and the callback URL explained plainly, then a YAML API test that obtains a token and uses it in the next request.

OAuth 2.0 in plain terms

Think of a valet key. You do not give the valet your whole keyring, only a key that opens the door and starts the car for a limited time. OAuth 2.0 works the same way for APIs.

The specification, RFC 6749, says it more formally. It describes an approval interaction between the resource owner and the HTTP service, or a way for the application to obtain access on its own behalf. In both cases the client gets an access token, a string that carries a specific scope, a lifetime and other access attributes. The client then presents that token to the server that hosts the protected resources.

For API testing this matters because your test is the client. It has to ask for a token, carry it into later requests and notice when it stops working.

The four roles

RFC 6749 defines four roles.

  • Resource owner: an entity capable of granting access to a protected resource. When it is a person, it is called an end-user.
  • Resource server: the server hosting the protected resources, which accepts requests that carry access tokens.
  • Client: the application making protected resource requests on behalf of the resource owner and with its authorization.
  • Authorization server: the server that issues access tokens to the client after authenticating the resource owner and obtaining authorization.

In an automated test, your test runner plays the client. The API under test is the resource server, and the login service it trusts is the authorization server.

Access tokens and refresh tokens

An access token is a credential used to access protected resources. It is a string that represents an authorization issued to the client, and tokens represent specific scopes and durations of access. The lifetime comes back in the token response as expires_in, which the RFC recommends servers include and defines as the lifetime in seconds.

A refresh token is a separate credential. The authorization server issues it to the client so the client can obtain a new access token when the current one becomes invalid or expires. Issuing a refresh token is optional at the discretion of the authorization server, so a token response without one is not a bug.

That gives a test three things worth checking: that a token arrives, that its lifetime is present, and that the refresh path works when the server offers one.

Grant types, and 2-legged versus 3-legged OAuth

The specification defines four grant types: authorization code, implicit, resource owner password credentials and client credentials. It also allows extension grant types.

Two of them map to the common labels 2-legged and 3-legged OAuth. Those two labels are common usage, not RFC 6749 vocabulary, so treat the mapping below as shorthand.

  • 3-legged usually means the authorization code grant. The client directs the resource owner to the authorization server through its user-agent, and the authorization server directs the owner back to the client with an authorization code. Three parties are involved: the user, the client and the server.
  • 2-legged usually means the client credentials grant. It is used when the client acts on its own behalf, or when it requests protected resources based on an authorization previously arranged with the authorization server. No end user is involved.

A CI job has no browser and no person to click Approve, so the 2-legged shape is usually the one a test uses.

What the callback URL does

What people call the callback URL is the client's redirection endpoint in RFC 6749 terms. After its interaction with the resource owner, the authorization server redirects the user-agent to that endpoint. The RFC requires that the redirection endpoint URI be an absolute URI and that it must not include a fragment component.

The client sets the endpoint with the authorization server during client registration or when it makes the authorization request. In practice, keep one per environment so a staging client never redirects to production.

JWT versus OAuth 2.0

A common question is how JWT and OAuth 2.0 differ. They sit at different levels. OAuth 2.0 is an authorization framework. A JSON Web Token, defined in RFC 7519, is a compact, URL-safe means of representing claims to be transferred between two parties. RFC 6749 says the access token string is usually opaque to the client, so a JWT is one format a server may choose for the token, not something OAuth requires.

Testing a token flow in a YAML API test

Keep the test as small as your other REST API test cases: get a token, pass it to the next request, and fail fast if the token step is wrong. DevTools lets a step read a field from an earlier response with the {{NodeName.response.body.field}} form. A JavaScript node can read context.<Node>.response and throw to fail the flow, which is the pattern the login-flow post uses to extract access_token.

flows:
  - name: TokenFlow
    variables:
      - name: CLIENT_SECRET
        value: '{{#env:OAUTH_CLIENT_SECRET}}'
    steps:
      - request:
          name: GetToken
          method: POST
          url: '{{BASE_URL}}/oauth/token'
          headers:
            Content-Type: application/json
          body:
            grant_type: client_credentials
            client_id: ci-client
            client_secret: '{{CLIENT_SECRET}}'
      - js:
          name: Token
          code: |
            export default function(ctx) {
              const r = ctx.GetToken?.response;
              if (r?.status !== 200) throw new Error("Token request failed: " + r?.status);
              if (!r?.body?.access_token) throw new Error("No access_token");
              if (typeof r?.body?.expires_in !== "number") throw new Error("No expires_in");
              return { token: r.body.access_token };
            }
          depends_on: GetToken
      - request:
          name: GetProfile
          method: GET
          url: '{{BASE_URL}}/api/me'
          headers:
            Authorization: Bearer {{Token.token}}
          depends_on: Token

Adapt the token request body to whatever your authorization server expects. The OAuth client credentials template exchanges client credentials for an access token and uses it to call a protected API. The secret is read from the environment with the {{#env:NAME}} syntax, which is meant for secrets in CI, so the committed file holds only the reference. To cover refresh, add a step that sends the stored refresh token and assert that a new access token comes back, only if your server issues refresh tokens.

For the full login, create, verify and delete sequence, read how to build an end-to-end API test. For scopes, rotation and keeping secrets out of logs, see API tokens in CI. DevTools runs these flows locally and in your own CI, and the GitHub Actions guide shows the wiring. If you want a hosted option, Stresseur Cloud at stresseur.com is a separate product from the same team.

Common questions

What are the different types of OAuth?

RFC 6749 defines four grant types: authorization code, implicit, resource owner password credentials and client credentials. 2-legged and 3-legged OAuth are common labels, not specification wording.

What is a callback URL in OAuth 2.0?

It is the client's redirection endpoint, where the authorization server redirects the user-agent after its interaction with the resource owner. It must be an absolute URI without a fragment.

Does OAuth 2.0 require a refresh token?

No. Issuing a refresh token is optional at the discretion of the authorization server.

Conclusion

OAuth 2.0 lets a client use a scoped, time-limited token instead of a password. Know the four roles, the access and refresh tokens and the grant you are using, and your test can request a token, chain it into the next call and fail early when the token step breaks. Keep secrets in the environment, and let the linked posts cover login sequences and CI token hygiene.