一键导入
m2m-client-credentials
Implement Machine-to-Machine (M2M) authentication using SSOJet OAuth2 Client Credentials flow for backend services and daemons.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Implement Machine-to-Machine (M2M) authentication using SSOJet OAuth2 Client Credentials flow for backend services and daemons.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Implement "Sign in with SSO" in native Android/Kotlin applications using SSOJet OIDC with AppAuth.
Implement "Sign in with SSO" in Angular SPA applications using SSOJet OIDC with PKCE.
Implement "Sign in with SSO" in ASP.NET Core applications using SSOJet OIDC middleware.
Implement "Sign in with SSO" in Go applications using SSOJet OIDC Authorization Code flow.
Implement "Sign in with SSO" in native iOS/Swift applications using SSOJet OIDC with AppAuth.
Implement "Sign in with SSO" in Java Spring Boot applications using SSOJet OIDC with Spring Security.
| name | m2m-client-credentials |
| description | Implement Machine-to-Machine (M2M) authentication using SSOJet OAuth2 Client Credentials flow for backend services and daemons. |
This expert AI assistant guide walks you through implementing Machine-to-Machine (M2M) authentication using SSOJet's OAuth2 Client Credentials grant. This flow is designed for backend services, daemons, CLIs, and APIs that need to authenticate without a user being present.
The Client Credentials flow is a two-step process:
There is no user interaction; this is a server-to-server authentication flow.
https://auth.ssojet.com/oauth2/token).// m2m-auth.js
const fetch = require('node-fetch');
async function getM2MToken() {
const response = await fetch('https://auth.ssojet.com/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.SSOJET_CLIENT_ID,
client_secret: process.env.SSOJET_CLIENT_SECRET,
audience: process.env.SSOJET_API_AUDIENCE, // optional
scope: 'read:data write:data', // requested scopes
}),
});
if (!response.ok) {
throw new Error(`Token request failed: ${response.statusText}`);
}
const data = await response.json();
console.log('Access Token:', data.access_token);
console.log('Expires In:', data.expires_in, 'seconds');
return data.access_token;
}
// Usage: call a protected API
async function callProtectedAPI() {
const token = await getM2MToken();
const response = await fetch('https://api.example.com/data', {
headers: { Authorization: `Bearer ${token}` },
});
const data = await response.json();
console.log('API Response:', data);
}
callProtectedAPI();
# m2m_auth.py
import os
import requests
def get_m2m_token():
response = requests.post(
'https://auth.ssojet.com/oauth2/token',
data={
'grant_type': 'client_credentials',
'client_id': os.getenv('SSOJET_CLIENT_ID'),
'client_secret': os.getenv('SSOJET_CLIENT_SECRET'),
'audience': os.getenv('SSOJET_API_AUDIENCE', ''),
'scope': 'read:data write:data',
},
)
response.raise_for_status()
data = response.json()
print(f"Access Token: {data['access_token']}")
print(f"Expires In: {data['expires_in']} seconds")
return data['access_token']
def call_protected_api():
token = get_m2m_token()
response = requests.get(
'https://api.example.com/data',
headers={'Authorization': f'Bearer {token}'},
)
print('API Response:', response.json())
if __name__ == '__main__':
call_protected_api()
// m2m_auth.go
package main
import (
"context"
"fmt"
"log"
"os"
"golang.org/x/oauth2"
"golang.org/x/oauth2/clientcredentials"
)
func main() {
config := &clientcredentials.Config{
ClientID: os.Getenv("SSOJET_CLIENT_ID"),
ClientSecret: os.Getenv("SSOJET_CLIENT_SECRET"),
TokenURL: "https://auth.ssojet.com/oauth2/token",
Scopes: []string{"read:data", "write:data"},
}
token, err := config.Token(context.Background())
if err != nil {
log.Fatal("Token request failed:", err)
}
fmt.Println("Access Token:", token.AccessToken)
fmt.Println("Expires:", token.Expiry)
// Use token to call a protected API
client := config.Client(context.Background())
resp, err := client.Get("https://api.example.com/data")
if err != nil {
log.Fatal("API call failed:", err)
}
defer resp.Body.Close()
fmt.Println("API Response Status:", resp.Status)
}
// M2MAuth.cs
using System.Net.Http.Headers;
var client = new HttpClient();
var tokenRequest = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "client_credentials"),
new KeyValuePair<string, string>("client_id", Environment.GetEnvironmentVariable("SSOJET_CLIENT_ID")!),
new KeyValuePair<string, string>("client_secret", Environment.GetEnvironmentVariable("SSOJET_CLIENT_SECRET")!),
new KeyValuePair<string, string>("scope", "read:data write:data"),
});
var tokenResponse = await client.PostAsync("https://auth.ssojet.com/oauth2/token", tokenRequest);
tokenResponse.EnsureSuccessStatusCode();
var tokenData = await tokenResponse.Content.ReadFromJsonAsync<TokenResponse>();
Console.WriteLine($"Access Token: {tokenData!.AccessToken}");
// Call a protected API
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenData.AccessToken);
var apiResponse = await client.GetStringAsync("https://api.example.com/data");
Console.WriteLine($"API Response: {apiResponse}");
record TokenResponse(
[property: System.Text.Json.Serialization.JsonPropertyName("access_token")] string AccessToken,
[property: System.Text.Json.Serialization.JsonPropertyName("expires_in")] int ExpiresIn
);
# Get M2M token
curl -X POST https://auth.ssojet.com/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=read:data write:data"
Tokens should be cached and reused until they expire. Here is a Node.js example:
// m2m-auth-cached.js
let cachedToken = null;
let tokenExpiry = 0;
async function getM2MToken() {
// Return cached token if still valid (with 60s buffer)
if (cachedToken && Date.now() < tokenExpiry - 60000) {
return cachedToken;
}
const response = await fetch('https://auth.ssojet.com/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.SSOJET_CLIENT_ID,
client_secret: process.env.SSOJET_CLIENT_SECRET,
scope: 'read:data write:data',
}),
});
const data = await response.json();
cachedToken = data.access_token;
tokenExpiry = Date.now() + data.expires_in * 1000;
return cachedToken;
}
SSOJET_CLIENT_ID and SSOJET_CLIENT_SECRET.