atiken插值c++_(基础篇 03)C++ 获取 access token

百度 AIP 开放平台使用 OAuth2.0 授权调用开放 API,调用 API 时必须在 URL 中带上 access_token 参数。

请求 URL 数据格式

请求参数如下:

grant_type: 必须参数,固定为 client_credentials;

client_id: 必须参数,应用的 API Key;

client_secret: 必须参数,应用的 Secret Key;

获取结果

服务器返回的JSON文本参数如下:

access_token: 要获取的 Access Token;

expires_in: Access Token 的有效期(秒为单位,一般为 1 个月);

其他参数忽略,暂时不用;

以下代码为示例:

{

"refresh_token": "25.b55fe1d287227ca97aab219bb249b8ab.315360000.1798284651.282335-8574074",

"expires_in": 2592000,

"scope": "public wise_adapt",

"session_key": "9mzdDZXu3dENdFZQurfg0Vz8slgSgvvOAUebNFzyzcpQ5EnbxbF+hfG9DQkpUVQdh4p6HbQcAiz5RmuBAja1JJGgIdJI",

"access_token": "24.6c5e1ff107f0e8bcef8c46d3424a0e78.2592000.1485516651.282335-8574074",

"session_secret": "dfac94a3489fe9fca7c3221cbf7525ff"

}

若请求错误,服务器将返回的 JSON 文本包含以下参数:

error: 错误码;关于错误码的详细信息请参考下方鉴权认证错误码。

error_description: 错误描述信息,帮助理解和解决发生的错误。

以下为请求错误返回结果:

{

"error": "invalid_client",

"error_description": "unknown client id"

}

error

error_description

解释

invalid_client

unknown client id

API Key不正确

invalid_client

Client authentication failed

Secret Key不正确

C++ 代码

#include

#include

#include

#include

#include

#include

// callback function for curl

size_t writeCallback(void *ptr, size_t size, size_t nmemb, void *userdata)

{

std::string *str = dynamic_cast<:string>((std::string *)userdata);

str->append((char *)ptr, size * nmemb);

return size * nmemb;

}

// get access token from server by get method

std::string getTokenKey() {

std::string url = "https://aip.baidubce.com/oauth/2.0/token";

std::string apikey = "这里更改为对应应用的 API Key";

std::string secritkey = "这里更改为对应应用的 Secrit Key";

std::map<:string std::string> params;

std::string response;

params["grant_type"] = "client_credentials";

params["client_id"] = apikey;

params["client_secret"] = secritkey;

// append url with parameters

for (auto it = params.begin(); it != params.end(); ++it) {

url += (it == params.begin() ? "?" : "&") + it->first + "=" + it->second;

}

CURL *curl = curl_easy_init();

struct curl_slist * slist = NULL;

curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); // set callback function

curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); // set var to receive return info from callback function

curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);

curl_easy_setopt(curl, CURLOPT_VERBOSE, false);

int status_code = curl_easy_perform(curl);

curl_easy_cleanup(curl);

curl_slist_free_all(slist);

Json::Value obj;

if (status_code != CURLcode::CURLE_OK) {

obj["curl_error_code"] = status_code;

return obj.toStyledString();

}

// parse json string

JSONCPP_STRING error;

Json::CharReaderBuilder builder;

const std::unique_ptr<:charreader> reader(builder.newCharReader());

reader->parse(response.data(), response.data() + response.size(), &obj, &error);

std::string access_token = obj["access_token"].asString();

return access_token;

}

// write messages to file

int write_string_to_file_append(const std::string & file_string, const std::string str)

{

std::ofstream OsWrite(file_string, std::ofstream::app);

OsWrite << str;

OsWrite << std::endl;

OsWrite.close();

return 0;

}

int main(int argc, char *argv[])

{

std::string tokenKey;

tokenKey = getTokenKey();

std::cout << "Token Key: " << tokenKey << "\n";

std::string filename = "tokenKey.db";

write_string_to_file_append(filename, tokenKey);

system("pause");

exit(EXIT_SUCCESS);

}

代码分析

std::string url = "https://aip.baidubce.com/oauth/2.0/token";

std::string apikey = "这里更改为对应应用的 API Key";

std::string secritkey = "这里更改为对应应用的 Secrit Key";

std::map<:string std::string> params;

std::string response;

params["grant_type"] = "client_credentials";

params["client_id"] = apikey;

params["client_secret"] = secritkey;

// append url with parameters

for (auto it = params.begin(); it != params.end(); ++it) {

url += (it == params.begin() ? "?" : "&") + it->first + "=" + it->second;

}

上面这段代码主要用于获取最终的请求 URL。因为这里使用的是 get 方法来获取 access token,所以需要将所有参数添加到 URL 中。params 用于存储请求参数,response 表示请求结果。for 循环则是将各个参数和 URL 使用 ? 和 & 连接起来。最终 URL 的一个示例如下:

https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=Va5yQRHlA4Fq5eR3LT0vuXV4&client_secret=0rDSjzQ20XUj5itV6WRtznPQSzr5pVw2&

CURL *curl = curl_easy_init();

struct curl_slist * slist = NULL;

curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); // set callback function

curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); // set var to receive return info from callback function

curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);

curl_easy_setopt(curl, CURLOPT_VERBOSE, false);

int status_code = curl_easy_perform(curl);

curl_easy_cleanup(curl);

curl_slist_free_all(slist);

上面这段代码主要是对 URL 请求进行设置,并请求,结果通过回调函数返回给 response。关于这里面的部分函数的使用方法可以参考:The Easy interface

curl_easy_init 函数必须是第一个要调用的函数,并且它返回一个 CURL 类型的简易句柄,必须将该 CURL 简易句柄用作 easy 接口中其他函数的输入。

curl_easy_setopt 用来告诉libcurl如何表现。通过设置适当的选项,应用程序可以更改libcurl的行为。这里设置的几个参数解释如下:

options

说明

URL to work on

Custom HTTP headers

Callback for writing data

Data pointer to pass to the write callback

Do not install signal handlers

Verify the SSL certificate

Verify the host name in the SSL certificate

Display verbose information

更多 Curl 的 options 参考 curl_easy_setopt。

// callback function for curl

size_t writeCallback(void *ptr, size_t size, size_t nmemb, void *userdata)

{

std::string *str = dynamic_cast<:string>((std::string *)userdata);

str->append((char *)ptr, size * nmemb);

return size * nmemb;

}

上面这段代码是回调函数,一旦收到需要保存的数据,libcurl 就会立即调用此回调函数。对于大多数传输,此回调将被调用多次,每次调用都会传递另一块数据。ptr 指向传递的数据,该数据的大小为 nmemb;大小始终为 1。关于该函数的使用说明可以参考 CURLOPT_WRITEFUNCTION explained 和 getinmemory.c。

Json::Value obj;

if (status_code != CURLcode::CURLE_OK) {

obj["curl_error_code"] = status_code;

return obj.toStyledString();

}

// parse json string

JSONCPP_STRING error;

Json::CharReaderBuilder builder;

const std::unique_ptr<:charreader> reader(builder.newCharReader());

reader->parse(response.data(), response.data() + response.size(), &obj, &error);

std::string access_token = obj["access_token"].asString();

上面这段代码主要将字符串转换为 Json 格式,然后获取 access_token 值。

另外我们在调用接口获取到 access token 后,可以将其存储到文件中,因为每个 access token 的有效期为 30 天,所以可以重复使用直到过期。以下代码为将字符串写入文件和从文件读入。

int writeFile(const std::string & fileString, const std::string &str) {

std::ofstream out(fileString, std::ios::binary);

if (out.is_open()) {

out << str;

out.close();

}

return 0;

}

int readFile(const std::string & fileString, std::string &str) {

std::ifstream in(fileString);

if (!in.is_open()) {

str = "";

return -1;

}

char buffer[256];

while (!in.eof()) {

in.getline(buffer, sizeof(buffer));

}

str = buffer;

return 0;

}

MICROSOFT FOUNDATION CLASS LIBRARY : ZSCPascal AppWizard has created this ZSCPascal application for you. This application not only demonstrates the basics of using the Microsoft Foundation classes but is also a starting point for writing your application. This file contains a summary of what you will find in each of the files that make up your ZSCPascal application. ZSCPascal.h This is the main header file for the application. It includes other project specific headers (including Resource.h) and declares the CZSCPascalApp application class. ZSCPascal.cpp This is the main application source file that contains the application class CZSCPascalApp. ZSCPascal.rc This is a listing of all of the Microsoft Windows resources that the program uses. It includes the icons, bitmaps, and cursors that are stored in the RES subdirectory. This file can be directly edited in Microsoft Developer Studio. resSCPascal.ico This is an icon file, which is used as the application s icon. This icon is included by the main resource file ZSCPascal.rc. resSCPascal.rc2 This file contains resources that are not edited by Microsoft Developer Studio. You should place all resources not editable by the resource editor in this file. ZSCPascal.reg This is an example .REG file that shows you the kind of registration settings the framework will set for you. You can use this as a .REG file to go along with your application or just delete it and rely on the default RegisterShellFileTypes registration. ZSCPascal.clw This file contains information used by ClassWizard to edit existing classes or add new classes. ClassWizard also uses this file to store information needed to create and edit message maps and dialog data maps and to create prototype member functions. For the main frame window: MainFrm.h, MainFrm.cpp These files contain the frame class CMainFrame, which is derived from CMDIFrameWnd and controls all MDI frame features. resToolbar.bmp This bitmap file is used to create tiled images for the toolbar. The initial toolbar and status bar are constructed in the CMainFrame class. Edit this toolbar bitmap along with the array in MainFrm.cpp to add more toolbar buttons. AppWizard creates one document type and one view: ZSCPascalDoc.h, ZSCPascalDoc.cpp - the document These files contain your CZSCPascalDoc class. Edit these files to add your special document data and to implement file saving and loading (via CZSCPascalDoc::Serialize). ZSCPascalView.h, ZSCPascalView.cpp - the view of the document These files contain your CZSCPascalView class. CZSCPascalView objects are used to view CZSCPascalDoc objects. resSCPascalDoc.ico This is an icon file, which is used as the icon for MDI child windows for the CZSCPascalDoc class. This icon is included by the main resource file ZSCPascal.rc. Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file named ZSCPascal.pch and a precompiled types file named StdAfx.obj. Resource.h This is the standard header file, which defines new resource IDs. Microsoft Developer Studio reads and updates this file. Other notes: AppWizard uses "TODO:" to indicate parts of the source code you should add to or customize. If your application uses MFC in a shared DLL, and your application is in a language other than the operating system s current language, you will need to copy the corresponding localized resources MFC40XXX.DLL from the Microsoft Visual C++ CD-ROM onto the system or system32 directory, and rename it to be MFCLOC.DLL. ("XXX" stands for the language abbreviation. For example, MFC40DEU.DLL contains resources translated to German.) If you don t do this, some of the UI elements of your application will remain in the language of the operating system.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值