Use cases
This API gets the user’s accessToken and is a key step in implementing user identity authentication. Common use cases include:
- After a user signs in, exchange the authorization code (
code) for a valid access credential.
- Before the
accessToken expires, use the refreshToken to renew it automatically and avoid frequent re-authorization.
- A third-party enterprise app integrates with the DingTalk unified sign-in system to implement single sign-on (SSO).
- An enterprise app calls protected APIs on behalf of a user from its backend service.
Developers should properly manage the lifecycle of the accessToken. We recommend caching it locally and setting up an automatic refresh mechanism to ensure stable API calls.
When using the access token, note the following:
- The
accessToken is valid for 7,200 seconds (2 hours). Repeated requests within the validity period return the same result and automatically renew it. After expiration, a new accessToken is returned.
- Each app’s
accessToken is independent. Cache the token by app to avoid confusion.
Request
| Basic information | |
|---|
| HTTP URL | https://api.dingtalk.io/v1.0/oauth2/userAccessToken |
| HTTP Method | POST |
| Supported app types | appType-Internal app appType-Third-party enterprise app appType-Third-party personal app |
| Required permissions | permission-open_app_api_base-Basic permission to obtain user access credentials for DingTalk Open APIs |
Request body
| Name | Type | Required | Example | Description |
|---|
| clientId | String | Yes | dingxxx | App ID. You can use the AppId of the Scan QR Code sign-in app or the third-party personal mini program. - For an internal app, pass the app’s AppKey. - For a third-party enterprise app, pass the app’s SuiteKey. - For a third-party personal app, pass the app’s AppId. |
| clientSecret | String | Yes | 1234 | App secret. - For an internal app, pass the app’s AppSecret. - For a third-party enterprise app, pass the app’s SuiteSecret. - For a third-party personal app, pass the app’s AppSecret. |
| code | String | No | abcd | OAuth 2.0 temporary authorization code. Third-party enterprise apps must integrate with the unified authorization suite or Get the access credential of the signed-in user to get the temporary authorization code authCode. |
| refreshToken | String | No | abcd | OAuth 2.0 refresh token, obtained from the previous API response. It is valid for 30 days. |
| grantType | String | Yes | authorization_code | - To exchange an authorization code for a token, pass authorization_code. In this case, the code parameter is required. - To exchange a refresh token for a new token, pass refresh_token. In this case, the refreshToken parameter is required. |
Request example
curl -X POST 'https://api.dingtalk.io/v1.0/oauth2/userAccessToken' \
-H 'Content-Type: application/json' \
-d '{
"clientId": "dingxxx",
"clientSecret": "1234",
"code": "abcd",
"refreshToken": "abcd",
"grantType": "authorization_code"
}'
Java
// This file is auto-generated, don't edit it. Thanks.
package com.aliyun.sample;
import com.aliyun.tea.*;
import com.aliyun.teautil.*;
import com.aliyun.dingtalkoauth2_1_0.*;
import com.aliyun.dingtalkoauth2_1_0.models.*;
import com.aliyun.teaopenapi.*;
import com.aliyun.teaopenapi.models.*;
public class Sample {
/**
* Initialize the account Client using a Token
* @return Client
* @throws Exception
*/
public static com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {
Config config = new Config();
config.protocol = "https";
config.regionId = "central";
return new com.aliyun.dingtalkoauth2_1_0.Client(config);
}
public static void main(String[] args_) throws Exception {
java.util.List<String> args = java.util.Arrays.asList(args_);
com.aliyun.dingtalkoauth2_1_0.Client client = Sample.createClient();
GetUserTokenRequest getUserTokenRequest = new GetUserTokenRequest()
.setClientId("dingxxx")
.setClientSecret("1234")
.setCode("abcd")
.setRefreshToken("abcd")
.setGrantType("authorization_code");
try {
client.getUserToken(getUserTokenRequest);
} catch (TeaException err) {
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// err contains the code and message properties, which help locate the issue
}
} catch (Exception _err) {
TeaException err = new TeaException(_err.getMessage(), _err);
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// err contains the code and message properties, which help locate the issue
}
}
}
}
Python
# -*- coding: utf-8 -*-
# This file is auto-generated, don't edit it. Thanks.
import sys
from typing import List
from alibabacloud_dingtalk.oauth2_1_0.client import Client as dingtalkoauth2_1_0Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_dingtalk.oauth2_1_0 import models as dingtalkoauth_2__1__0_models
from alibabacloud_tea_util.client import Client as UtilClient
class Sample:
def __init__(self):
pass
@staticmethod
def create_client() -> dingtalkoauth2_1_0Client:
"""
Initialize the account Client using a Token
@return: Client
@throws Exception
"""
config = open_api_models.Config()
config.protocol = 'https'
config.region_id = 'central'
return dingtalkoauth2_1_0Client(config)
@staticmethod
def main(
args: List[str],
) -> None:
client = Sample.create_client()
get_user_token_request = dingtalkoauth_2__1__0_models.GetUserTokenRequest(
client_id='dingxxx',
client_secret='1234',
code='abcd',
refresh_token='abcd',
grant_type='authorization_code'
)
try:
client.get_user_token(get_user_token_request)
except Exception as err:
if not UtilClient.empty(err.code) and not UtilClient.empty(err.message):
# err contains the code and message properties, which help locate the issue
pass
@staticmethod
async def main_async(
args: List[str],
) -> None:
client = Sample.create_client()
get_user_token_request = dingtalkoauth_2__1__0_models.GetUserTokenRequest(
client_id='dingxxx',
client_secret='1234',
code='abcd',
refresh_token='abcd',
grant_type='authorization_code'
)
try:
await client.get_user_token_async(get_user_token_request)
except Exception as err:
if not UtilClient.empty(err.code) and not UtilClient.empty(err.message):
# err contains the code and message properties, which help locate the issue
pass
if __name__ == '__main__':
Sample.main(sys.argv[1:])
PHP
<?php
// This file is auto-generated, don't edit it. Thanks.
namespace AlibabaCloud\SDK\Sample;
use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Dingtalk;
use \Exception;
use AlibabaCloud\Tea\Exception\TeaError;
use AlibabaCloud\Tea\Utils\Utils;
use Darabonba\OpenApi\Models\Config;
use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Models\GetUserTokenRequest;
class Sample {
/**
* Initialize the account Client using a Token
* @return Dingtalk Client
*/
public static function createClient(){
$config = new Config([]);
$config->protocol = "https";
$config->regionId = "central";
return new Dingtalk($config);
}
/**
* @param string[] $args
* @return void
*/
public static function main($args){
$client = self::createClient();
$getUserTokenRequest = new GetUserTokenRequest([
"clientId" => "dingxxx",
"clientSecret" => "1234",
"code" => "abcd",
"refreshToken" => "abcd",
"grantType" => "authorization_code"
]);
try {
$client->getUserToken($getUserTokenRequest);
}
catch (Exception $err) {
if (!($err instanceof TeaError)) {
$err = new TeaError([], $err->getMessage(), $err->getCode(), $err);
}
if (!Utils::empty_($err->code) && !Utils::empty_($err->message)) {
// err contains the code and message properties, which help locate the issue
}
}
}
}
$path = __DIR__ . \DIRECTORY_SEPARATOR . '..' . \DIRECTORY_SEPARATOR . 'vendor' . \DIRECTORY_SEPARATOR . 'autoload.php';
if (file_exists($path)) {
require_once $path;
}
Sample::main(array_slice($argv, 1));
Go
// This file is auto-generated, don't edit it. Thanks.
package main
import (
"os"
util "github.com/alibabacloud-go/tea-utils/service"
dingtalkoauth2_1_0 "github.com/alibabacloud-go/dingtalk/oauth2_1_0"
openapi "github.com/alibabacloud-go/darabonba-openapi/client"
"github.com/alibabacloud-go/tea/tea"
)
/**
* Initialize the account Client using a Token
* @return Client
* @throws Exception
*/
func CreateClient () (_result *dingtalkoauth2_1_0.Client, _err error) {
config := &openapi.Config{}
config.Protocol = tea.String("https")
config.RegionId = tea.String("central")
_result = &dingtalkoauth2_1_0.Client{}
_result, _err = dingtalkoauth2_1_0.NewClient(config)
return _result, _err
}
func _main (args []*string) (_err error) {
client, _err := CreateClient()
if _err != nil {
return _err
}
getUserTokenRequest := &dingtalkoauth2_1_0.GetUserTokenRequest{
ClientId: tea.String("dingxxx"),
ClientSecret: tea.String("1234"),
Code: tea.String("abcd"),
RefreshToken: tea.String("abcd"),
GrantType: tea.String("authorization_code"),
}
tryErr := func()(_e error) {
defer func() {
if r := tea.Recover(recover()); r != nil {
_e = r
}
}()
_, _err = client.GetUserToken(getUserTokenRequest)
if _err != nil {
return _err
}
return nil
}()
if tryErr != nil {
var err = &tea.SDKError{}
if _t, ok := tryErr.(*tea.SDKError); ok {
err = _t
} else {
err.Message = tea.String(tryErr.Error())
}
if !tea.BoolValue(util.Empty(err.Code)) && !tea.BoolValue(util.Empty(err.Message)) {
// err contains the code and message properties, which help locate the issue
}
}
return _err
}
func main() {
err := _main(tea.StringSlice(os.Args[1:]))
if err != nil {
panic(err)
}
}
Node.js
// This file is auto-generated, don't edit it
import Util from '@alicloud/tea-util';
import dingtalkoauth2_1_0, * as $dingtalkoauth2_1_0 from '@alicloud/dingtalk/oauth2_1_0';
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
import * as $tea from '@alicloud/tea-typescript';
export default class Client {
/**
* Initialize the account Client using a Token
* @return Client
* @throws Exception
*/
static createClient(): dingtalkoauth2_1_0 {
let config = new $OpenApi.Config({ });
config.protocol = "https";
config.regionId = "central";
return new dingtalkoauth2_1_0(config);
}
static async main(args: string[]): Promise<void> {
let client = Client.createClient();
let getUserTokenRequest = new $dingtalkoauth2_1_0.GetUserTokenRequest({
clientId: "dingxxx",
clientSecret: "1234",
code: "abcd",
refreshToken: "abcd",
grantType: "authorization_code",
});
try {
await client.getUserToken(getUserTokenRequest);
} catch (err) {
if (!Util.empty(err.code) && !Util.empty(err.message)) {
// err contains the code and message properties, which help locate the issue
}
}
}
}
Client.main(process.argv.slice(2));
C#
// This file is auto-generated, don't edit it. Thanks.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Tea;
using Tea.Utils;
namespace AlibabaCloud.SDK.Sample
{
public class Sample
{
/**
* Initialize the account Client using a Token
* @return Client
* @throws Exception
*/
public static AlibabaCloud.SDK.Dingtalkoauth2_1_0.Client CreateClient()
{
AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config();
config.Protocol = "https";
config.RegionId = "central";
return new AlibabaCloud.SDK.Dingtalkoauth2_1_0.Client(config);
}
public static void Main(string[] args)
{
AlibabaCloud.SDK.Dingtalkoauth2_1_0.Client client = CreateClient();
AlibabaCloud.SDK.Dingtalkoauth2_1_0.Models.GetUserTokenRequest getUserTokenRequest = new AlibabaCloud.SDK.Dingtalkoauth2_1_0.Models.GetUserTokenRequest
{
ClientId = "dingxxx",
ClientSecret = "1234",
Code = "abcd",
RefreshToken = "abcd",
GrantType = "authorization_code",
};
try
{
client.GetUserToken(getUserTokenRequest);
}
catch (TeaException err)
{
if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message))
{
// err contains the code and message properties, which help locate the issue
}
}
catch (Exception _err)
{
TeaException err = new TeaException(new Dictionary<string, object>
{
{ "message", _err.Message }
});
if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message))
{
// err contains the code and message properties, which help locate the issue
}
}
}
}
}
C
// This file is auto-generated, don't edit it. Thanks.
#include <alibabacloud/dingtalkoauth_2__1__0.hpp>
#include <alibabacloud/open_api.hpp>
#include <boost/any.hpp>
#include <darabonba/core.hpp>
#include <darabonba/util.hpp>
#include <iostream>
#include <map>
using namespace std;
Alibabacloud_Dingtalkoauth2_1_0::Client createClient() {
shared_ptr<Alibabacloud_OpenApi::Config> config = make_shared<Alibabacloud_OpenApi::Config>();
config->protocol = make_shared<string>("https");
config->regionId = make_shared<string>("central");
return Alibabacloud_Dingtalkoauth2_1_0::Client(config);
}
int main(int argc, char *args[]) {
args;
shared_ptr<Alibabacloud_Dingtalkoauth2_1_0::Client> client = make_shared<Alibabacloud_Dingtalkoauth2_1_0::Client>(createClient());
shared_ptr<Alibabacloud_Dingtalkoauth2_1_0::GetUserTokenRequest> getUserTokenRequest = make_shared<Alibabacloud_Dingtalkoauth2_1_0::GetUserTokenRequest>(map<string, boost::any>({
{"clientId", boost::any(string("dingxxx"))},
{"clientSecret", boost::any(string("1234"))},
{"code", boost::any(string("abcd"))},
{"refreshToken", boost::any(string("abcd"))},
{"grantType", boost::any(string("authorization_code"))}
}));
try {
client->getUserToken(getUserTokenRequest);
}
catch (std::exception &err) {
if (!Darabonba_Util::Client::empty(err.code) && !Darabonba_Util::Client::empty(err.message)) {
// err contains the code and message properties, which help locate the issue
}
}
}
Response
Response body
| Name | Type | Example | Description |
|---|
| accessToken | String | abcd | The generated accessToken, used for authentication in subsequent API calls. |
| refreshToken | String | abcd | The generated refresh_token. Use this refresh token to periodically obtain the user’s accessToken. |
| expireIn | Long | 7200 | Expiration time, in seconds. |
| corpId | String | corpxxxx | The organization ID of the selected organization. |
Response example
HTTP/1.1 200 OK
Content-Type:application/json
{
"accessToken" : "abcd",
"refreshToken" : "abcd",
"expireIn" : 7200,
"corpId" : "corpxxxx"
}
Error codes
If an error occurs when calling this API, find the solution by error message in the Error codes (legacy Server-side) document.