winhttp 访问https_「winhttp」C++用winhttp实现https访问服务器 – seo实验室

winhttp 访问https_「winhttp」C++用winhttp实现https访问服务器 – seo实验室winhttp由于项目升级,在数据传输过程中需要经过oauth2.0认证,访问服务器需要https协议。首先,实现C++代码访问https服务器,实现Get和post功能,在网上搜索一通,发现各种各样的都有,有的很简单,有的稍微复杂。结果MSDN介绍的比较简洁一点官方网址:https://docs.microsoft.com/en-us/windows/desktop/winhttp/ssl-i…

大家好,又见面了,我是你们的朋友全栈君。

winhttp

由于项目升级,在数据传输过程中需要经过oauth2.0认证,访问服务器需要https协议。

首先,实现C++代码访问https 服务器,实现Get和post功能,在网上搜索一通,发现各种各样的都有,有的很简单,有的稍微复杂。结果MSDN介绍的比较简洁一点

官方网址:https://docs.microsoft.com/en-us/windows/desktop/winhttp/ssl-in-winhttp

网友翻译:https://blog.csdn.net/edger2heaven/article/details/45664297

我们的要求还是相对比较简单,OAuth 采用客户端模式(client credentials)

参考阮一峰blog

http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向”服务提供商”进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求”服务提供商”提供服务,其实不存在授权问题。

winhttp 访问https_「winhttp」C++用winhttp实现https访问服务器 - seo实验室

它的步骤如下:

(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。

(B)认证服务器确认无误后,向客户端提供访问令牌。

A步骤中,客户端发出的HTTP请求,包含以下参数:

granttype:表示授权类型,此处的值固定为”clientcredentials”,必选项。

scope:表示权限范围,可选项。POST /token HTTP/1.1

Host: server.example.com

authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

content-Type: APPlication/x-www-form-urlencoded

grant_type=client_credentials

认证服务器必须以某种方式,验证客户端身份。

B步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。

HTTP/1.1 200 OK

Content-Type: application/json;charset=UTF-8

cache-Control: no-store

pragma: no-cache

{

“access_token”:”2YotnFZFEjr1zCsicMWpAA”,

“token_type”:”example”,

“expires_in”:3600,

“example_parameter”:”example_value”

}

以下是POST的代码,代码有点瑕疵,不能通用于普通项目,但是流程是通用的。

GET的代码也是大同小异,只是https头部信息有所不用

#include “stdafx.h”

#include “windows.h”

#include “winhttp.h”

#include “wchar.h”

#include “wincrypt.h”

#include

#pragma comment(lib, “Winhttp.lib”)

#pragma comment(lib, “Crypt32.lib”)

wstring string2wstring(const string &str)

{

_bstr_t tmp = str.c_str();

wchar_t* pwchar = (wchar_t*)tmp;

wstring ret = pwchar;

return ret;

}

void winhttp_client_post(){

LPSTR pszData = “WinHttpWriteData Example”;

Dword dwBytesWritten = 0;

BOOL bResults = FALSE;

HINTERNET hsession = NULL,

hConnect = NULL,

hrequest = NULL;

// Use WinHttpOpen to obtain a session handle.

hSession = WinHttpOpen( L”A WinHTTP Example Program/1.0″,

WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,

WINHTTP_NO_PROXY_NAME,

WINHTTP_NO_PROXY_BYPASS, 0);

// Specify an HTTP server.

if (hSession)

hConnect = WinHttpConnect( hSession, L”www.wingtiptoys.com”,

INTERNET_DEFAULT_HTTPS_PORT, 0);

// Create an HTTP Request handle.

if (hConnect)

hRequest = WinHttpOpenRequest( hConnect, L”POST”,

L”/token”,

NULL, WINHTTP_NO_referer,

WINHTTP_DEFAULT_ACCEPT_types,

0);

// Set HTTP Options

dword dwTimeOut = 3000;

DWORD dwFlags =SECURITY_FLAG_ignore_UNKNOWN_CA |

SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE |

SECURITY_FLAG_IGNORE_CERT_CN_INvalid |

SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;

BOOL bRet = WinHttpSetOption(hRequest, WINHTTP_OPTION_CONNECT_TIMEOUT, &dwTimeOut, sizeof(DWORD));

bRet = WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwFlags, sizeof(dwFlags));

bRet = WinHttpSetOption(hRequest, WINHTTP_OPTION_CLIENT_CERT_context, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0);

//加上OAuth认证需要的header信息:

std::string client_id = “test client id”;

std::string client_secure = “test client security”;

// client id and secure need base64 encode

std::wstring strHeader = L”Content-type:application/x-www-form-urlencoded\r\n”;

strHeader += L”Authorization: Basic “;

//strHeader += string2wstring(tmsstring) +L”\r\n”; //tmsstring is client and secure after base64 encoding

bRet = WinHttpAddRequestHeader(hRequest, strHeader.c_str(), strHeader.length(), WINHTTP_ADDREQ_FLAG_ADD|WINHTTP_ADDREQ_FLAG_REPLACE);

// Send a Request.

std::string strTmp = “grant_type=client_credentials”; //OAuth认证模式是客户端模式

if (hRequest)

bResults = WinHttpSendRequest( hRequest,

WINHTTP_NO_ADDITIONAL_headers,

0, (LPVOID)strTmp.c_str(), strTmp.length(),

strTmp.length(), 0);

// Write data to the server. don’t need this step

/*if (bResults)

bResults = WinHttpWriteData( hRequest, pszData,

(DWORD)strlen(pszData),

&dwBytesWritten);

*/

// End the request.

if (bResults)

bResults = WinHttpReceiveresponse( hRequest, NULL);

// Report any ERRORs.

if (!bResults)

printf(“Error %d has occurred.\n”,GetLastError());

//接收服务器返回数据

if(bRet)

{

char *pszOutBuf;

DWORD dwSize = 0;

DWORD dwDownLoaded = 0;

std::string strJson; //返回的是Json格式

do

{

if (!WinHttpQueryDataAvailable(hRequest, &dwSize))

{

//error log

}

pszOutBuf = new char[dwSize+1];

zeromemory(pszOutBuf, dwSize+1);

if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuf, dwSize, &dwDownLoaded) )

{

//error log

}

strJson += pszOutBuf;

}while(dwSize > 0);

}

// Close any open handles.

if (hRequest) WinHttpCloseHandle(hRequest);

if (hConnect) WinHttpCloseHandle(hConnect);

if (hSession) WinHttpCloseHandle(hSession);

}

相关阅读

大家都知道Press any key to continue…,在windows下的bat中只需要一个pause命令即可,那么shell的批处理该怎样实现这个功能呢,其实

问题描述:

自己实现一个MyStrcat函数,要和C语言库函数的strcat函数完成同样的功能。

问题分析: 首先我们要了解一下strcat函数它到

示例图:activity.xml文件布局<?xml version=”1.0″ encoding=”utf-8″?>

xmlns:android=”http://schemas.android

Structured Streaming 实现思路与实现概述

[酷玩 Spark] Structured Streaming 源码解析系列 ,返回目录请 猛戳这里「腾讯·广点

实现单选功能的控件一组RadioButton必须放在一个RadioGroup中 意思就是说单选按钮中的值我们可以看作是一个数组也就是这里说的

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/157597.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【实践与问题解决38】win10桌面图标变成一个空白图标「建议收藏」

    【实践与问题解决38】win10桌面图标变成一个空白图标「建议收藏」1问题描述:桌面部分图标显示空白但是点击可以正常打开程序(快捷方式没有改变路径依旧可以打开程序)2问题原因:Windows10系统中,为了加速图标的显示,当第一次对图标进行显示时,系统会对文件或程序的图标进行缓存。之后,当我们再次进入到某个文件夹需要显示该图标时,系统会直接从缓存中读取数据,从而大大加快显示速度。也正因为如此,当缓存文件出现问题时,就会引发系统图标显示不正常。3解决方案:3.1方案一:只需要将有问题的图标缓存文件删除掉,让系统重新建立图标缓存即可。第一步:

    2022年10月9日
    3
  • clion永久激活注册码 3月最新注册码

    clion永久激活注册码 3月最新注册码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月14日
    111
  • mysql8 安装启动报错[通俗易懂]

    注意点1my.ini配置,其中这两项一定要按这个格式,双引号及双反斜杠,否则初始化时会报下面的错basedir="D:\\tool\\MYSQL\\mysql-8.0.12-winx64"datadir="D:\\tool\\MYSQL\\mysql-8.0.12-winx64\\data"[mysqld]#Removeleading#andsettothe…

    2022年4月15日
    73
  • go语言runtime_中台怎么理解

    go语言runtime_中台怎么理解funcCaller(skipint)(pcuintptr,filestring,lineint,okbool)参数:skip是要提升的堆栈帧数,0-当前函数,1-上一层函数,….返回值:pc是uintptr这个返回的是函数指针file是函数所在文件名目录line所在行号ok是否可…

    2025年7月29日
    2
  • PL/SQL中declare、begin关键字解释

    PL/SQL中declare、begin关键字解释使用declare或begin关键字开头的bai叫匿名块,每次使用均需要进行编译,不能存储在数据库中且不能被其他PL/SQL调用。而存储过程,存储函数,触发器等叫命名块,一经编译后面就可直接调用,且可以存储在数据库中,被其他PL/SQL调用;declareagenumber(4);–声明一个参数baia类型du为number类型长度为4beginselectteaAgeintoagefromteacherwhereteaid=122;–查询teaid为12

    2022年8月22日
    6
  • java xml 中文乱码_java写xml中文乱码解决方法

    java xml 中文乱码_java写xml中文乱码解决方法用java写xml文件,发现写完后xml文件的中文就变成了乱码。解决办法:把xml文件的头部编码改为utf-8,StreamResult编码方式也改为utf-8,StreamResult类充当转换结果的持有者,可以为XML、纯文本、HTML或某些其他格式的标记。publicStringcreateXMLbyId(){Coursec=courseService.getCou…

    2022年7月16日
    80

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号