Generate a signed JWT for SSO
Basic Setup
Using the provided secret signing key, create an endpoint following a below example
Nodejs (Express)
dependencies:
npm install jsonwebtoken@9.0.2
index.js:
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const SECRET = 'your-secret-signing-key';//Usually fetched from a secret manager
app.get('/generateOctopusSsoToken', (req, res) => {
const loggedUserId = howeverYouFetchYourCurrentUserId(req)
const token = jwt.sign(
{ sub: loggedUserId }, SECRET, { expiresIn: '1h', algorithm: 'HS256' }
);
res.json({ token });
});
app.listen(3000, () => console.log('Server running on port 3000'));
Python (Flask)
requirement.txt:
PyJWT==2.10.1
app.py:
from flask import Flask, jsonify
import jwt
import datetime
app = Flask(__name__)
SECRET = 'your-secret-key'# Usually fetched from a secret manager
@app.route('/generateOctopusSsoToken', methods=['GET'])
def generate_token():
exp = datetime.datetime.utcnow() + datetime.timedelta(hours=1)
token = jwt.encode({'sub': 'yourUserId', 'exp': exp}, SECRET, algorithm='HS256')
return jsonify({'token': token})
if __name__ == '__main__':
app.run(port=3000)
Java (Spring)
pom.xml:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.6</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <!-- JSON codec; alternatively jjwt-gson, jjwt-orgjson -->
<version>0.12.6</version>
<scope>runtime</scope>
</dependency>
App.java:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
@RestController
class TokenController {
private static final String SECRET =
"your-secret-key";
private static final Key KEY = Keys.hmacShaKeyFor(SECRET.getBytes());
@GetMapping("/generateOctopusSsoToken")
public Map<String, String> genToken() {
Map<String, String> resp = new HashMap<>();
try {
String token = Jwts.builder()
.subject("yourUserId")
.expiration(new Date(System.currentTimeMillis() + 3_600_000)) // 1 h
.signWith(KEY)
.compact();
resp.put("token", token);
} catch (Exception e) {
resp.put("error", "Failed to generate token: " + e.getMessage());
}
return resp;
}
}
sub: has to be a persistent and immutable identifier for the user.
exp: the expiration does not determine when the user will be logged out from octopus. if you want to expire the octopus session you must call octopus.disconnectUser()
Avoid using mutable values for the sub
attribute like an email or nickname, as they can change over time.
Instead, use your own user ID if it fits the immutability requirements, or
generate a unique octopusId associated with the user to ensure long-term consistency and flexibility.
If the same user logs in again on another device or after reinstalling your application, the same sub
value must be used.
Advanced Setup
For a more advanced setup, you can provide us a custom verification (private or public) key and specify the supported algorithm of your choice.