Este documento descreve como uma aplicação personalizada que usa JSON Web Token (JWT) obtém um token de acesso ao Drive and Photo Service (PDS).
Aplicações JWT
Uma aplicação JWT é uma aplicação personalizada que usa o mecanismo de JSON Web Token (JWT) para autenticação de identidade.
O servidor da aplicação JWT assina dados com uma chave privada para gerar uma JWT Assertion. Essa string funciona como credencial de acesso ao servidor PDS, configurado com a chave pública correspondente.

Casos de uso
Sua organização possui um sistema de software interno com contas próprias e você quer que os usuários façam login pela página interna para usar os recursos do PDS.
Sua organização mantém um sistema de contas e um portal de login independentes, e o objetivo é integrar esse portal ao PDS para criar um sistema de armazenamento em nuvem baseado nas contas atuais.
Visão geral do fluxo de trabalho
No console do PDS, crie um domínio personalizado e uma aplicação JWT.
Use o algoritmo RSA para gerar um par de chaves pública e privada. Salve a chave pública no servidor PDS e a chave privada no servidor da aplicação JWT.
O servidor da aplicação JWT codifica os dados e os assina com a chave privada para gerar uma JWT Assertion e enviá-la ao servidor PDS.
O servidor PDS valida a JWT Assertion com a chave pública. Após a validação bem-sucedida, ele retorna um token de acesso ao servidor da aplicação JWT. Use esse token para chamar as APIs do PDS.
Procedimento
Etapa 1: Configure chaves
1,1 Crie ou selecione um domínio
No console do Drive and Photo Service, na página Domain List, clique em Create Domain. No painel aberto, insira um Domain Name (por exemplo, "Drive Demo") e uma Description. Defina o Data Storage Mode como Standard Mode, ative a opção Enable Initial Drive, selecione Custom Size, defina o tamanho do Drive (por exemplo, 10 GB) e clique em OK.
1,2 Crie ou selecione uma aplicação
Acesse a página de detalhes do domínio e, na aba Applications, crie ou selecione uma aplicação.
Na caixa de diálogo Create Application, em Application Access Method, selecione Access as Application. Em Type, escolha Access with JWT Authentication. Insira um Application Name (por exemplo, Demo Drive). Para Permission Scope, selecione Custom e marque as permissões DRIVE.ALL, SHARE.ALL, FILE.ALL, USER.ALL, STORAGE.ALL, STORAGEFILE.LIST, ACCOUNT.ALL e BATCH. Clique em OK.
1,3 Defina a chave pública
Após criar ou selecionar uma aplicação, defina sua chave pública.
Na página de detalhes do domínio, selecione a aba Applications. Na seção My Applications, localize a aplicação desejada e clique em Set Public Key na coluna Actions.
Na caixa de diálogo exibida, clique no link No key pair? Click here to generate one para gerar um novo par de chaves. Cole a chave pública gerada na caixa de texto Public Key PEM.
Depois de gerar o par de chaves, copie a chave privada e salve-a em um local seguro. Em seguida, clique em OK.
As alterações na chave pública entram em vigor em até cinco minutos.
Etapa 2: Obter um token de acesso
2,1 Construir e assinar a JWT Assertion
No servidor da aplicação, codifique os dados do payload e assine-os com a chave privada usando o algoritmo de criptografia especificado para gerar uma JWT Assertion. O código Node.js abaixo fornece um exemplo:
const JWT = require('jsonwebtoken');
function signAssertion({ domain_id, client_id, user_id, privateKeyPEM }) {
var now_sec = parseInt(Date.now() / 1000);
var opt = {
iss: client_id,
sub: user_id,
sub_type: "user",
aud: domain_id,
jti: Math.random().toString(36).substring(2),
exp: now_sec + 60,
// iat: now_sec, // Issued At (current Unix time in seconds)
// nbf: '', // Not Before (Unix time in seconds)
auto_create: false,
};
return JWT.sign(opt, privateKeyPEM, {
algorithm: "RS256",
});
}
Claims do payload JWT
|
Parâmetro |
Obrigatório |
Tipo |
Descrição |
|
iss |
Sim |
String |
ID da aplicação. |
|
sub |
Sim |
String |
ID do usuário ou do domínio. O valor depende da claim |
|
sub_type (campo estendido) |
Sim |
String |
Tipo de conta. Valores válidos: |
|
aud |
Sim |
String |
ID do domínio. |
|
jti |
Sim |
String |
Identificador exclusivo do JWT, gerado pela aplicação. O comprimento deve ser de 16 a 128 caracteres. Recomendamos o uso de UUID. |
|
exp |
Sim |
Integer |
Tempo de expiração do JWT, como timestamp Unix em segundos. A janela de tempo entre as claims |
|
iat |
Não |
Integer |
Momento de emissão, como timestamp Unix em segundos. O token não pode ser usado antes desse horário. Exemplo: |
|
nbf |
Não |
Integer |
Tempo "não antes de", como timestamp Unix em segundos. Se não especificado, o padrão é a hora atual. A janela de tempo entre |
|
auto_create (campo estendido) |
Não |
Boolean |
Especifica se o sistema deve criar um usuário automaticamente caso não exista. Padrão: |
Para mais informações sobre bibliotecas JWT e métodos de assinatura, consulte o site oficial do JWT.
2,2 Obter um token de acesso
Chame a operação Authorize para trocar a JWT Assertion por um access_token.
POST /v2/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&client_id=${APP_ID}&assertion=xxxxxxxxxx
Defina o cabeçalho Content-Type da requisição como application/x-www-form-urlencoded. Coloque os parâmetros no corpo da requisição.
Parâmetros da requisição
|
Parâmetro |
Obrigatório |
Tipo |
Descrição |
|
grant_type |
Sim |
String |
Tipo de concessão. Defina como a constante de string |
|
client_id |
Sim |
String |
ID da aplicação. |
|
assertion |
Sim |
String |
JWT Assertion gerada na etapa anterior. |
Exemplo de resposta
{
"access_token": "eyJh****eQdnUTsEk4",
"refresh_token": "kL***Lt",
"expires_in": 7200,
"token_type": "Bearer"
}
Após o servidor da aplicação receber o access_token, retorne o token à aplicação cliente. Inclua o access_token nas chamadas de API para acessar recursos do usuário no PDS.
2,3 Atualizar o token de acesso
Um access_token obtido via fluxo JWT tem validade de 2 horas. Após a expiração, use o refresh_token para obter um novo access_token. O refresh_token é válido por 7 dias. Quando ele expirar, repita as etapas 2,1 e 2,2 para gerar um token completamente novo. Alternativamente, repita as etapas 2,1 e 2,2 a qualquer momento para obter um novo access_token.
Chame a operação Authorize para trocar o refresh_token por um novo access_token:
POST /v2/oauth/token
Content-Type: application/x-www-form-urlencoded
client_id=${APP_ID}&refresh_token=${refresh_token}&grant_type=refresh_token&redirect_uri=${REDIRECT_URI}
|
Parâmetro |
Obrigatório |
Tipo |
Descrição |
|
client_id |
Sim |
String |
ID da aplicação. |
|
refresh_token |
Sim |
String |
|
|
grant_type |
Sim |
String |
Tipo de concessão. Defina como a constante de string |
|
redirect_uri |
Sim |
String |
URL de callback especificada durante a criação da aplicação. |
Etapa 3: Usar a Basic UI (opcional)
Caso não queira desenvolver sua própria interface e a Basic UI oficial atenda às suas necessidades, use-a diretamente.
Método 1: Abrir em uma nova janela
Use window.open para abrir a Basic UI e passe o token de acesso usando postMessage.
Código de exemplo:
const endpoint = `https://${domain_id}.apps.aliyunpds.com`
const url = `${endpoint}/accesstoken?origin=${location.origin}`
var win = window.open(url)
window.addEventListener('message', onMessage, false)
async function onMessage(e) {
if (e.data.code == 'token' && e.data.message == 'ready') {
var result = await getToken(); // Obtain the access token from your server.
// result = {"access_token": ...}
win.postMessage({
code: 'token',
message: result
}, endpoint || '*')
window.removeEventListener('message', onMessage)
}
}
Método 2: Incorporar na página de login personalizada
Incorpore a Basic UI em uma página de login personalizada usando um iframe.
Para permitir que a Basic UI atualize o token automaticamente, configure a URL da página de login personalizada e o ID da aplicação JWT nas configurações do sistema.
Acesse a página Enterprise Settings > Advanced Customization. Conclua a configuração na seção Custom Login and Logout. Também é possível configurar uma Custom Logout Page URL. Após essa configuração, ao fazer logout, o sistema redirecionará os usuários automaticamente para a página de logout personalizada e limpará o estado de login.
Quando um usuário faz login, a página de login personalizada abre em um iframe em vez da página de login padrão da Basic UI.
Após um login bem-sucedido, passe os tokens para a página host usando postMessage.

if(parent!=self){
let origin = ''
parent.postMessage({
code: 'token',
message: {
access_token: 'xxxx',
refresh_token: 'xxxx',
...
}
}, endpoint || "*")
}
Apêndice 1: Implementação de código Node.js
O código de exemplo abaixo mostra como uma aplicação JWT obtém e atualiza um access_token.
const fs = require('fs')
const JWT = require('jsonwebtoken');
const axios = require('axios')
const DOMAIN_ID = '' // Your domain ID
const APP_ID = '' // Your application ID
const USER_ID = '' // The user ID
const PRIVATE_KEY_PEM = '' // The private key configured in Step 1.3
const PRE = `https://${DOMAIN_ID}.api.aliyunpds.com`
async function init() {
try {
// Replace the following variables with your actual values.
var params = {
domain_id: DOMAIN_ID,
client_id: APP_ID,
user_id: USER_ID,
privateKeyPEM: PRIVATE_KEY_PEM,
};
var assertion = signAssertion(params)
var obj = await getToken(assertion)
return obj.data
} catch (e) {
if (e.response) {
console.log(e.response.status)
console.log(e.response.headers)
console.log(e.response.data)
} else {
console.error(e)
}
}
}
function signAssertion({ domain_id, client_id, user_id, privateKeyPEM }) {
var now_sec = parseInt(Date.now()/1000)
var opt = {
iss: client_id,
sub: user_id,
sub_type: 'user',
aud: domain_id,
jti: Math.random().toString(36).substring(2),
exp: now_sec + 300,
// iat: now_sec,
// nbf: '',
auto_create: true,
};
return JWT.sign(opt, privateKeyPEM, {
algorithm: 'RS256'
});
}
async function getToken(assertion) {
return await axios({
method: 'post',
url: PRE + '/v2/oauth/token',
// Note: Set the Content-Type header to application/x-www-form-urlencoded.
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
// Note: Place the request parameters in the request body.
data: params({
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
client_id: APP_ID,
assertion
})
})
}
async function refreshToken(refresh_token) {
return await axios({
method: 'post',
url: PRE + '/v2/oauth/token',
// Note: Set the Content-Type header to application/x-www-form-urlencoded.
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
// Note: Place the request parameters in the request body.
data: params({
grant_type: 'refresh_token',
client_id: APP_ID,
refresh_token,
})
})
}
function params(m){
const params = new URLSearchParams();
for(var k in m){
params.append(k, m[k]);
}
return params;
}
// Test the functions.
;(async ()=>{
let result = await init()
console.log(result) // Returns a token object: {access_token:...}. For the object structure, see Appendix 2.
// After the access_token expires
refreshToken(result.refresh_token) // Returns a new token object: {access_token:...}. For the object structure, see Appendix 2.
})();
Apêndice 2: Estrutura do objeto de token
Exemplo de resposta:
{
"access_token": "eyJhbG.....g7M0p28",
"refresh_token": "62f1acc.......9b781f3",
"expires_in": 7200,
"token_type": "Bearer",
"..." : "..."
}
Para mais informações sobre os parâmetros, consulte Obter um token de acesso.