How to get AUTHORIZATION_CODE with Jira OAuth?

From the document:
https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/

This way can get authorization code:

https://auth.atlassian.com/authorize?
  audience=api.atlassian.com&
  client_id=YOUR_CLIENT_ID&
  scope=REQUESTED_SCOPE_ONE%20REQUESTED_SCOPE_TWO&
  redirect_uri=https://YOUR_APP_CALLBACK_URL&
  state=YOUR_USER_BOUND_VALUE&
  response_type=code&
  prompt=consent

I created an app in develop console and set a callback url http://localhost:3000/oauth/callback in Authorization. When I tried to get the authorization code in terminal:

AUTH_URL="https://auth.atlassian.com/authorize\?audience\=api.atlassian.com\&client_id\=[MY_CLIENT_ID]\&scope\=read%3Ajira-work\&redirect_uri\=http%3A%2F%2Flocalhost%3A3000%2Foauth%2Fcallback\&state\=6d7493eaf1e6e58c8a0cdc976c41aac428061bb349d3635b77441fa8e68ea21b\&response_type\=code\&prompt\=consent"

Then started a callback page local.

const express = require('express');
const app = express();
const port = 3000;

app.get('/oauth/callback', (req, res) => {
    const code = req.query.code;
    const state = req.query.state;

    res.send(`Received authorization code: ${code}, State: ${state}`);
});

app.listen(port, () => {
    console.log(`Server is running on http://localhost:${port}`);
});

However, when run curl -X GET "$AUTH_URL" in terminal, I got this error:

<!doctype html><html lang="en"><head><title>HTTP Status 400 – Bad Request</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 400 – Bad Request</h1></body></html>

Where is wrong? Is it possible to add http://localhost:3000/oauth/callback to develop console’s Callback URL?

I wonder if your problem isn’t the the callback URL at all but is how you are calling the authorize endpoint “in terminal”. Are you trying to curl it? I hope it’s clear that OAuth 2.0’s authorization code flow requires the browser.

There’s nothing wrong with a localhost callback URL. In this previous thread, I shared a CLI tool that does that:

Thank you @ibuchanan .
Yes, I tried to curl it curl -X GET "$AUTH_URL" and got a 400 static page.

If localhost works well for a callback, I think it’s right to run it from terminal via curl.

I tried your script. After setting ATLASSIAN_APP_3LO_CLIENT_ID and ATLASSIAN_APP_3LO_CLIENT_SECRET and run it by sh atlassian-oauth2.sh, got this error:

# Request authorization

POST https://auth.atlassian.com/oauth/token                                     
Headers:                                                                        
  Content-Type: application/x-www-form-urlencoded                               
Form post:                                                                      
  grant_type: refresh_token                                                     
  refresh_token: --silent                                                       
  client_id: ATLASSIAN_APP_3LO_CLIENT_ID                                   
  client_secret: ATLASSIAN_APP_3LO_CLIENT_SECRET
Response:                                                                       
{                                                                               
  "error": "unauthorized_client",
  "error_description": "refresh_token is invalid"
}

  ERROR   403: unauthorized_client                                              
GET /me HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br
Authorization: Bearer 
Connection: keep-alive
Host: api.atlassian.com
User-Agent: xh/0.22.0

HTTP/2.0 401 Unauthorized
atl-traceid: 600c1a0ed07e4ad6853bdde111b11584
content-length: 37
content-type: application/json
date: Sat, 20 Apr 2024 07:52:03 GMT
nel: {"failure_fraction": 0.001, "include_subdomains": true, "max_age": 600, "report_to": "endpoint-1"}
report-to: {"endpoints": [{"url": "https://dz8aopenkvv6s.cloudfront.net"}], "group": "endpoint-1", "include_subdomains": true, "max_age": 600}
server: AtlassianEdge
strict-transport-security: max-age=63072000; preload
x-content-type-options: nosniff
x-failure-category: FAILURE_CLIENT_AUTH_MISMATCH
x-frame-options: SameOrigin
x-trace-id: 600c1a0ed07e4ad6853bdde111b11584
x-xss-protection: 1; mode=block

{
    "code": 401,
    "message": "Unauthorized"
}

This way it seems didn’t set a redirect_uri. Are the client_id and client_secret enough to use?
Why the document shows only client_id?

No. The authorize URL is not a REST API. It will never work through curl.

Hi @ibuchanan
Thank you.
I use simple-oauth2 library with a callback url and access from browser, it works.