Я пытаюсь преобразовать api узла с запросом в запросы C #. Код узла делится на два блока.
Первый блок «Аутентификация»:
const AUTHENTICATION_PATH = '/_api/authentication/sessions/usercredentials'
const BASE_URL = 'www.avanza.se'
authenticate(credentials) {
if (!credentials) {
return Promise.reject('Missing credentials.')
}
if (!credentials.username) {
return Promise.reject('Missing credentials.username.')
}
if (!credentials.password) {
return Promise.reject('Missing credentials.password.')
}
if (!(this._authenticationTimeout >= MIN_INACTIVE_MINUTES &&
this._authenticationTimeout <= MAX_INACTIVE_MINUTES)) {
return Promise.reject(`Session timeout not in range ${MIN_INACTIVE_MINUTES} - ${MAX_INACTIVE_MINUTES} minutes.`)
}
return new Promise((resolve, reject) => {
const data = {
maxInactiveMinutes: this._authenticationTimeout,
password: credentials.password,
username: credentials.username
}
request({
method: 'POST',
path: constants.paths.AUTHENTICATION_PATH,
data
}).then((response) => {
// No second factor requested, continue with normal login
if (typeof response.body.twoFactorLogin === 'undefined') {
return Promise.resolve(response)
}
const tfaOpts = response.body.twoFactorLogin;
if (tfaOpts.method !== 'TOTP') {
return Promise.reject(`Unsupported second factor method ${tfaOpts.method}`)
}
const totpCode = (credentials.totpSecret) ? totp(credentials.totpSecret) : credentials.totp
if (!totpCode) {
return Promise.reject('Missing credentials.totp or credentials.totpSecret')
}
return request({
method: 'POST',
path: constants.paths.TOTP_PATH,
data: {
method: 'TOTP',
totpCode
},
headers: {
Cookie: `AZAMFATRANSACTION=${tfaOpts.transactionId}`
}
})
}).then((response) => {
this._authenticated = true
this._credentials = credentials
this._securityToken = response.headers['x-securitytoken']
this._authenticationSession = response.body.authenticationSession
this._pushSubscriptionId = response.body.pushSubscriptionId
this._customerId = response.body.customerId
// Re-authenticate after timeout minus one minute
this._scheduleReauth((this._authenticationTimeout - 1) * 60 * 1000)
if (this._socket) {
this._socketRestart()
}
resolve({
securityToken: this._securityToken,
authenticationSession: this._authenticationSession,
pushSubscriptionId: this._pushSubscriptionId,
customerId: this._customerId
})
}).catch((e) => {
this._pushSubscriptionId = undefined
reject(e)
})
})
}
Второй блок с запросом:
function request(options) {
if (!options) {
return Promise.reject('Missing options.')
}
const data = JSON.stringify(options.data)
return new Promise((resolve, reject) => {
const req = https.request({
host: BASE_URL,
port: 443,
method: options.method,
path: options.path,
headers: Object.assign({
'Accept': '*/*',
'Content-Type': 'application/json',
'User-Agent': USER_AGENT,
'Content-Length': data.length
}, options.headers)
}, (response) => {
const body = []
response.on('data', chunk => body.push(chunk))
response.on('end', () => {
let parsedBody = body.join('')
try {
parsedBody = JSON.parse(parsedBody)
} catch (e) {
debug('Received non-JSON data from API.', body)
}
const res = {
statusCode: response.statusCode,
statusMessage: response.statusMessage,
headers: response.headers,
body: parsedBody
}
if (response.statusCode < 200 || response.statusCode > 299) {
reject(res)
} else {
resolve(res)
}
})
})
if (data) {
req.write(data)
}
req.on('error', e => reject(e))
req.end()
})
}
Теперь моя реализация C #:
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.avanza.se/_api/authentication/sessions/usercredentials");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Host = "www.avanza.se";
httpWebRequest.Method = "POST";
httpWebRequest.Accept = "*/*";
httpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36";
httpWebRequest.Timeout = 3000;
Holdern korv = new Holdern()
{
maxInactiveMinutes = 30,
username = "usernamestring",
password = "passwordstring"
};
string json = JsonConvert.SerializeObject(korv);
httpWebRequest.ContentLength = json.Length;
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Проблема в том, что я получаю ошибку 405. Чего мне не хватает?
Но если я вручную сделаю это с почтальоном, это выдаст мне 500 ошибок. Кто-нибудь, кто может определить, что не так?
Карл