curl --request PUT \
--url https://app.stockshift.io/api/v1/apps/push-token \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"token": "7d1c2a4f0b6e9c3d8a5f2e1b4c7d0a9e6f3b8c5d2a1e4f7b0c3d6e9a2f5b8c1d"
}
'import requests
url = "https://app.stockshift.io/api/v1/apps/push-token"
payload = { "token": "7d1c2a4f0b6e9c3d8a5f2e1b4c7d0a9e6f3b8c5d2a1e4f7b0c3d6e9a2f5b8c1d" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.stockshift.io/api/v1/apps/push-token",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'token' => '7d1c2a4f0b6e9c3d8a5f2e1b4c7d0a9e6f3b8c5d2a1e4f7b0c3d6e9a2f5b8c1d'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.stockshift.io/api/v1/apps/push-token"
payload := strings.NewReader("{\n \"token\": \"7d1c2a4f0b6e9c3d8a5f2e1b4c7d0a9e6f3b8c5d2a1e4f7b0c3d6e9a2f5b8c1d\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}Enregistrer le jeton push de l'application appelante
Enregistre le jeton que APNs ou FCM a remis à l’application, afin que le serveur puisse signaler à l’appareil qu’un flux a changé ou qu’un verrouillage, un effacement ou une déconnexion est en attente. Une notification push ne transporte que des ID, et l’application récupère le reste. L’appareil détient un seul jeton : envoyez-en un nouveau chaque fois que la plateforme le renouvelle. Le jeton d’accès doit avoir été émis pour une application; tout autre répond 404. La modification est consignée dans l’historique d’audit, sans le jeton push.
curl --request PUT \
--url https://app.stockshift.io/api/v1/apps/push-token \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"token": "7d1c2a4f0b6e9c3d8a5f2e1b4c7d0a9e6f3b8c5d2a1e4f7b0c3d6e9a2f5b8c1d"
}
'import requests
url = "https://app.stockshift.io/api/v1/apps/push-token"
payload = { "token": "7d1c2a4f0b6e9c3d8a5f2e1b4c7d0a9e6f3b8c5d2a1e4f7b0c3d6e9a2f5b8c1d" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.stockshift.io/api/v1/apps/push-token",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'token' => '7d1c2a4f0b6e9c3d8a5f2e1b4c7d0a9e6f3b8c5d2a1e4f7b0c3d6e9a2f5b8c1d'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.stockshift.io/api/v1/apps/push-token"
payload := strings.NewReader("{\n \"token\": \"7d1c2a4f0b6e9c3d8a5f2e1b4c7d0a9e6f3b8c5d2a1e4f7b0c3d6e9a2f5b8c1d\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "<string>",
"detail": "<string>",
"errors": {},
"feature": "<string>",
"reason": "<string>",
"attempts_left": 123,
"rule_ids": [
"<string>"
],
"witness": "<string>",
"blind_recount": true,
"flags": [
{
"flag": "<string>",
"facts": {},
"choices": [
"<string>"
]
}
]
}Autorisations
Comment les applications StockShift se connectent. L'application ouvre /apps/authorize dans le navigateur système avec un défi PKCE S256 et l'empreinte de sa clé d'appareil. Le membre s'y connecte, avec toutes les vérifications qu'applique le Web. Le navigateur renvoie un code à l'application, qui l'échange à POST /apps/token avec le vérificateur PKCE et une preuve DPoP (RFC 9449) signée par la clé d'appareil. La réponse contient un jeton d'accès d'une heure, envoyé comme jeton de type Bearer à chaque appel, et un jeton d'actualisation rotatif de 30 jours. Une actualisation exige une preuve DPoP avec le dernier nonce du serveur, si bien qu'un jeton d'actualisation volé est inutile sans la clé d'appareil. Une session prend fin 180 jours après la connexion au plus tard. Chaque requête d'application porte StockShift-Client: / (), par exemple ios/1.4.2 (311). Sous le minimum de GET /apps/version-policy, un appel reçoit la réponse 426 client_upgrade_required avec le minimum et le lien de la boutique. Sous la version deprecated-below, l'appel fonctionne et la réponse ajoute StockShift-Client-Deprecated: sunset=; minimum=. La connexion et la déconnexion, l'état de l'appareil, le reçu d'effacement, les appels de verrouillage par NIP et la politique de version répondent pour toutes les versions.
Corps
Le jeton de notification push qu'une application a obtenu d'APNs ou de FCM.
Le jeton d'appareil d'APNs (hexadécimal) ou le jeton d'enregistrement de FCM, tel que la plateforme l'a donné.
4096^[A-Za-z0-9_:\-]+$"7d1c2a4f0b6e9c3d8a5f2e1b4c7d0a9e6f3b8c5d2a1e4f7b0c3d6e9a2f5b8c1d"
Quels serveurs APNs connaissent le jeton : sandbox pour une application iOS ou macOS compilée depuis Xcode, sinon production, la valeur par défaut.
production Les serveurs de production d'APNs, pour les applications de l'App Store ou de TestFlight, et tout jeton FCM. |
sandbox Les serveurs de bac à sable d'APNs, pour les applications compilées depuis Xcode. |
production, sandbox Réponse
Aucun contenu
Cette page vous a-t-elle été utile ?