WebHU - Programozási kérdések és válaszok

401 engedélyezési hiba Windows Phone 8 értesítések

Megpróbálok értesítéseket küldeni a Windows Phone 8 alkalmazásomnak egy hitelesített szerver használatával, de 401-es hibaüzenetet kapok, amikor megpróbálok értesítést küldeni.

Követtem az MSDN-oldalakon található utasításokat, nevezetesen: http://msdn.microsoft.com/library/windows/apps/ff941099(v=vs.105).aspx ahol ez áll: The Key-Usage value of the TLS certificate must be set to include client authentication. Fogalmam sincs, hogy ez mit jelent, és az online keresés nem adj nekem is bármilyen nyomot.

Lehetséges, hogy ez hibás, vagy az én kódom, ami lent látható.

VB.NET-KÓD:

Private Async Sub ApplicationBarPin_Click(sender As Object, e As EventArgs)
    ' Holds the push channel that is created or found.
            Dim pushChannel As HttpNotificationChannel

            ' The name of our push channel.
            Dim channelName As String = "WindowsPhoneTrainTileNotification"

            ' Try to find the push channel.
            pushChannel = HttpNotificationChannel.Find(channelName)

            ' If the channel was not found, then create a new connection to the push service.
            If pushChannel Is Nothing Then
                pushChannel = New HttpNotificationChannel(channelName, "redsquirrelsoftware.co.uk")
                uri_timer = New DispatcherTimer
                uri_timer.Interval = TimeSpan.FromSeconds(5)
                AddHandler uri_timer.Tick, AddressOf UriTimerTick
                uri_timer.Start()

                ' Register for all the events before attempting to open the channel.
                AddHandler pushChannel.ChannelUriUpdated, AddressOf PushChannel_TileChannelUriUpdated
                AddHandler pushChannel.ErrorOccurred, AddressOf PushChannel_TileErrorOccurred

                pushChannel.Open()

                pushChannel.BindToShellTile()
            Else
                ' The channel was already open, so just register for all the events.
                AddHandler pushChannel.ChannelUriUpdated, AddressOf PushChannel_TileChannelUriUpdated
                AddHandler pushChannel.ErrorOccurred, AddressOf PushChannel_TileErrorOccurred

                Dim form As New MultipartFormDataContent()
                form.Add(New StringContent(Statics.getUserID), "userId")
                form.Add(New StringContent(pushChannel.ChannelUri.ToString()), "uri")
                form.Add(New StringContent(Statics.CurrentScheduleId), "scheduleId")

                Dim httpClient As HttpClient = New HttpClient()

                Dim response As HttpResponseMessage = Await httpClient.PostAsync("http://redsquirrelsoftware.co.uk/trains/push/WPTileSubscribe.php", form)
            End If

            ShellTile.Create(New Uri("/Route.xaml?scheduleId=" & scheduleId, UriKind.Relative), secondaryTile, True) 'Create SecondaryTile and pass querystring to navigation url.
        Catch ex As Exception
        End Try

    End If
End Sub

Private Async Sub PushChannel_TileChannelUriUpdated(sender As Object, e As NotificationChannelUriEventArgs)
    Dim form As New MultipartFormDataContent()
    form.Add(New StringContent(Statics.getUserID), "userId")
    form.Add(New StringContent(e.ChannelUri.ToString()), "uri")
    form.Add(New StringContent(Statics.CurrentScheduleId), "scheduleId")

    Dim httpClient As HttpClient = New HttpClient()

    Dim response As HttpResponseMessage = Await httpClient.PostAsync("http://redsquirrelsoftware.co.uk/trains/push/WPTileSubscribe.php", form)
End Sub

Private Sub PushChannel_TileErrorOccurred(sender As Object, e As NotificationChannelErrorEventArgs)
    MessageBox.Show("Error creating live tile, please try again")
End Sub

Private Async Sub UriTimerTick(sender As Object, e As EventArgs)
    Try
        If pushChannel.ChannelUri IsNot Nothing Then
            Dim form As New MultipartFormDataContent()
            form.Add(New StringContent(Statics.getUserID), "userId")
            form.Add(New StringContent(pushChannel.ChannelUri.ToString()), "uri")
            form.Add(New StringContent(Statics.CurrentScheduleId), "scheduleId")

            Dim httpClient As HttpClient = New HttpClient()

            Dim response As HttpResponseMessage = Await httpClient.PostAsync("http://redsquirrelsoftware.co.uk/trains/push/WPTileSubscribe.php", form)
            uri_timer.Stop()
        End If
    Catch ex As Exception
    End Try

End Sub

Ez a várt módon működik, és az URI az adatbázisomban van tárolva (HTTPS-sel kezdve, és az URI-ban sem tartalmaz throttledthirdparty-t, ami arra utal, hogy ez a kód működik).

train_movements.php:

<?php
include 'WindowsPhoneTilePush.php';
$WPN = new WPN($packageSID, $clientSecret);
$xml_data = $WPN->build_tile_xml($sched_id, strtoupper($loc), "$eventTypeStr $dt (". strtolower($variation_status) . ")");
$WPNResponse = $WPN->post_tile($uri, $xml_data);
if($WPNResponse->error == true) {
    $my_file = $logFile;
    $handle = fopen($my_file, 'a') or die('Cannot open file:  '.$my_file);
    $data = $WPNResponse->httpCode . ":" . $WPNResponse->message . "\n";
    fwrite($handle, $data);
}
?>

WindowsPhoneTilePush.php: (adaptált: itt)

<?php
class WPNTypesEnum{       
    const Toast = 'wns/toast';
    const Badge = 'wns/badge';
    const Tile  = 'wns/tile';
    const Raw   = 'wns/raw';
}                         

class WPNResponse{
    public $message = '';
    public $error = false;
    public $httpCode = '';

    function __construct($message, $httpCode, $error = false){
        $this->message = $message;
        $this->httpCode = $httpCode;
        $this->error = $error;
    }
}

class WPN{            
    private $access_token = '';
    private $sid = '';
    private $secret = '';

    function __construct($sid, $secret){
        $this->sid = $sid;
        $this->secret = $secret;
    }

    private function get_access_token(){
        if($this->access_token != ''){
            return;
        }

        $str = "grant_type=client_credentials&client_id=$this->sid&client_secret=$this->secret&scope=notify.windows.com";
        $url = "https://login.live.com/accesstoken.srf";

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
        curl_setopt($ch, CURLOPT_POSTFIELDS, "$str");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        curl_close($ch);                       

        $output = json_decode($output);

        if(isset($output->error)){
            throw new Exception($output->error_description);
        }

        $this->access_token = $output->access_token;
    }

    public function build_tile_xml($tile_nav_uri, $wide2, $wide3){
        $msg =  "<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
                "<wp:Notification xmlns:wp=\"WPNotification\" Version=\"2.0\">" .
                "<wp:Tile Id=\"/Route.xaml?scheduleId=$tile_nav_uri\" Template=\"IconicTile\">" .
                //"<wp:SmallIconImage>$image_url_small</wp:SmallIconImage>" .
                //"<wp:IconImage>$image_url_large</wp:IconImage>" .
                //"<wp:WideContent1>$wide1</wp:WideContent1>" .
                "<wp:WideContent2>$wide2</wp:WideContent2>" .
                "<wp:WideContent3>$wide3</wp:WideContent3>" .
                //"<wp:Count>$count</wp:Count>" .
                //"<wp:Title>$title</wp:Title>" .
                //"<wp:BackgroundColor>#00FFFFFF</wp:BackgroundColor>" .
                "</wp:Tile>" .
                "</wp:Notification>";

        return $msg;

    }

    public function post_tile($uri, $xml_data, $type = WPNTypesEnum::Tile, $tileTag = '', $count = 0){
        if($this->access_token == ''){
            $this->get_access_token();
        }

        $headers = array('Content-Type: text/xml', "Content-Length: " . strlen($xml_data), "X-WNS-Type: $type", "Authorization: Bearer $this->access_token");
        if($tileTag != ''){
            array_push($headers, "X-WNS-Tag: $tileTag");
        }

        $ch = curl_init($uri);
        # Tiles: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868263.aspx
        # http://msdn.microsoft.com/en-us/library/windows/apps/hh465435.aspx
        curl_setopt($ch, CURLOPT_CAPATH, "/var/www/clients/client1/web1/ssl/");
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POSTFIELDS, "$xml_data");
        curl_setopt($ch, CURLOPT_VERBOSE, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $response = curl_getinfo( $ch );
        curl_close($ch);

        $code = $response['http_code'];
        if($code == 200){
            return new WPNResponse('Successfully sent message', $code);
        }
        else if($code == 401){
            $my_file = '/var/log/WPNotify.txt';
            $handle = fopen($my_file, 'a') or die('Cannot open file:  '.$my_file);
            $data = date("d-M-y H:i:s:") . "401 Authorisation Error:" . $this->access_token . "\n";
            fwrite($handle, $data);

            if($count == 10) {
                exit;
            }
            $this->access_token = '';
            return $this->post_tile($uri, $xml_data, $type, $tileTag, $count++);
        }
        else if($code == 410 || $code == 404){
            return new WPNResponse('Expired or invalid URI', $code, true);
        }
        else{
            return new WPNResponse('Unknown error while sending message', $code, true);
        }
    }
}
?>

Hiba lehet a kódomban, vagy az lehet, hogy nem állítom be megfelelően a backend dolgokat (a legtöbb MSDN-dokumentum a Windows Serverekre és az .aspx-re vonatkozik, ezért megpróbáltam replikálni ezeket az utasításokat, de lehet, hogy Valahol elromlott!).

Ha valaki tudna segíteni akár a kódhibák kijavításában, akár az SSL tanúsítvány kliens hitelesítésében, azt nagyon megköszönném!

Köszönöm, Jake


  • Keresse meg a 401-es HTTP-hibát, amely meglehetősen magától értetődő, és valószínűleg nem is a kód hektárnyi mennyiségével kapcsolatos, amelyeken átgázolunk. 30.07.2014
  • @RiggsFolly Tudom, mi az a 401-es hiba, csak miután az elmúlt 3 napot sikertelenül próbáltam megoldani, reméltem, hogy valaki itt tud majd rávilágítani a helyzetre. Tudom, hogy sok kód van, de ha kód nélkül tettem volna fel a kérdést, garantálom, hogy az első megjegyzés az lett volna, hogy "tegye közzé a kódját". 30.07.2014

Válaszok:


1

vessen egy pillantást a Windows értesítési szolgáltatásra: 401 érvénytelen token, amikor Toast-értesítést próbál létrehozni PHP-ben érvénytelen-token-n

győződjön meg arról, hogy az alkalmazás csomag SID-jét küldi el „client_id” paraméterként, nem pedig az alkalmazás client_id paraméterét, amikor hozzáférési token kér.

Ez nagyon zavaró, mivel mindkettő képes megszerezni az access_token-t a Microsoft kiszolgálójáról, de csak a csomag SID-je mellett kért token nem ad 401-es hibát a pirítós értesítés küldésekor.

26.08.2015
Új anyagok

A rádiógomb ellenőrzött eseményének használata a jQueryben
Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

Miért érdemes elkezdeni a kódolást 2023-ban?
01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

🎙 Random Noise #2  – Örökbefogadás és hit
az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..