iT邦幫忙

0

Line Notify 取得token的問題?php 5.6版本

  • 分享至 

  • twitterImage

參考資料: https://a-bad-engineer.blogspot.com/2018/01/line-line-notify-1.html

php 5.6版本 apache2.2.3

有一個功能出現了錯誤??之前還可以的,不知道為何不能用了??
新人加入Line Notify推播,取得code後,再次向Line取得token,就出現問題?

測試網址:(測試帳號!!)
http://ble.com.tw/Iot360/v00_line_notify.php
測試流程如下:
圖一
https://ithelp.ithome.com.tw/upload/images/20210220/20013294jgRgQ1VMN7.png
圖二
https://ithelp.ithome.com.tw/upload/images/20210220/20013294lERWNueMg3.png
圖三
https://ithelp.ithome.com.tw/upload/images/20210220/20013294C6Kmyvs1aF.png

我有將code,拿去用postman測試(註:這是我第一次用postman,參數如果設錯,請指教,thx)
https://ithelp.ithome.com.tw/upload/images/20210220/20013294oKqWvtBktu.png

還是一樣,回傳錯誤
{"status":400,"message":"invalid code","access_token":null}

這是我的php line notify程式碼??
http://220.132.53.237:1111/sharing/J41cjpU8w

感謝,thx

看更多先前的討論...收起先前的討論...
淺水員 iT邦大師 6 級 ‧ 2021-02-21 09:51:51 檢舉
我記得串line的app,body 是直接用 raw 丟 json
淺水員 iT邦大師 6 級 ‧ 2021-02-21 20:43:13 檢舉
抱歉我誤會了,我以為是 message api。
淺水員 .沒關係??
你有沒有在postman的Authorization設定你的access token
若沒有
Type請選擇 Bearer token
右側再貼上你的access token 發送應該就可以了
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
淺水員
iT邦大師 6 級 ‧ 2021-02-21 23:16:44
最佳解答

我剛剛看官方文件做的,可以拿到 access_token

env.php

<?php
//所註冊服務的 client id
const CLIENT_ID='';

//所註冊服務的 client secret
const CLIENT_SECRET='';

//所註冊服務的 callback URL(由 authLineToken.php 處理)
const AUTH_PAGE_URL='http://localhost/notify/authLineToken.php';

index.php

<?php
require(__DIR__.'/env.php');
?><!DOCTYPE html>
<html lang="Zh-Hant">
<head>
    <meta charset="utf-8">
    <title>首頁</title>
</head>
<body>
    <button onclick="redirectToLine()">讓 Line 通知我</button>
    <script>
        function redirectToLine() {
            let url='https://notify-bot.line.me/oauth/authorize';
            let params={
                response_type: 'code',
                client_id: '<?php echo CLIENT_ID;?>',
                redirect_uri: '<?php echo AUTH_PAGE_URL;?>',
                scope: 'notify',
                state: 'step1',
                response_mode: 'form_post'
            };
            url+='?'+Object.keys(params).map(key=>`${key}=${encodeURIComponent(params[key])}`).join('&');
            location.href=url;
        }
    </script>
</body>
</html>

authLineToken.php

<?php
require(__DIR__.'/env.php');

if(isset($_POST['state']) && $_POST['state']==='step1') {
    if(isset($_POST['code'])) {
        $ch=curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => 'https://notify-bot.line.me/oauth/token',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => [
                'grant_type' => 'authorization_code',
                'code' => $_POST['code'],
                'redirect_uri' => AUTH_PAGE_URL,
                'client_id' => CLIENT_ID,
                'client_secret' => CLIENT_SECRET
            ],
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_SSL_VERIFYPEER => 0,
        ]);
        $body=curl_exec($ch);
        $code=curl_getinfo($ch,  CURLINFO_RESPONSE_CODE);
        curl_close($ch);
        if($code===200) {
            $json=json_decode($body, true);
            echo 'access_token: '.(isset($json['access_token'])?$json['access_token']:'null');
        } else {
            echo '無法取得 access_token';
        }
    } elseif(isset($_POST['error']) && isset($_POST['error_description'])) {
        exit($_POST['error'].'<br>'.$_POST['error_description']);
    } else {
        exit('未知的錯誤');
    }
} else {
    exit('Bad Request');
}
看更多先前的回應...收起先前的回應...

奇怪了,我用你的程式嗎?? 修改一下,卻還是

step1
step1
9feQQ6HW6wl1wqUihiKXvQ
無法取得 access_token

測試網址
https://ble.com.tw/Iot360/w00_line_notify.php

<?php
//所註冊服務的 client id
const CLIENT_ID='X1zUzNSSqbJeokBalwdBmi';

//所註冊服務的 client secret
const CLIENT_SECRET='0h5PkTU6ZlymWE0soqXvTYxx8mkqfoEvur38XA3I2I5';

//所註冊服務的 callback URL(由 authLineToken.php 處理)
const AUTH_PAGE_URL='https://ble.com.tw/Iot360/w00_line_notify_call.php';

?>
<?php
 
?><!DOCTYPE html>
<html lang="Zh-Hant">
<head>
    <meta charset="utf-8">
    <title>首頁</title>
</head>
<body>
    <button onclick="redirectToLine()">讓 Line 通知我</button>
    <script>
        function redirectToLine() {
            let url='https://notify-bot.line.me/oauth/authorize';
            let params={
                response_type: 'code',
                client_id: '<?php echo CLIENT_ID;?>',
                redirect_uri: '<?php echo AUTH_PAGE_URL;?>',
                scope: 'notify',
                state: 'step1',
                response_mode: 'form_post'
            };
            url+='?'+Object.keys(params).map(key=>`${key}=${encodeURIComponent(params[key])}`).join('&');
            location.href=url;
        }
    </script>
</body>
</html>

第二支程式

<?php
//所註冊服務的 client id
const CLIENT_ID='X1zUzNSSqbJeokBalwdBmi';

//所註冊服務的 client secret
const CLIENT_SECRET='0h5PkTU6ZlymWE0soqXvTYxx8mkqfoEvur38XA3I2I5';

//所註冊服務的 callback URL(由 authLineToken.php 處理)
const AUTH_PAGE_URL='https://ble.com.tw/Iot360/w00_line_notify_call.php';

?>
<?php
echo $_POST['state'] .'<BR>';
echo $_POST['state'] .'<BR>';
echo $_POST['code'] .'<BR>';

if(isset($_POST['state']) && $_POST['state']==='step1') {
    if(isset($_POST['code'])) {
        $ch=curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => 'https://notify-bot.line.me/oauth/token',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => [
                'grant_type' => 'authorization_code',
                'code' => $_POST['code'],
                'redirect_uri' => AUTH_PAGE_URL,
                'client_id' => CLIENT_ID,
                'client_secret' => CLIENT_SECRET
            ],
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_SSL_VERIFYPEER => 0,
        ]);
        $body=curl_exec($ch);
        $code=curl_getinfo($ch,  CURLINFO_RESPONSE_CODE);
        curl_close($ch);
        if($code===200) {
            $json=json_decode($body, true);
            echo 'access_token: '.(isset($json['access_token'])?$json['access_token']:'null');
        } else {
            echo '無法取得 access_token';
        }
    } elseif(isset($_POST['error']) && isset($_POST['error_description'])) {
        exit($_POST['error'].'<br>'.$_POST['error_description']);
    } else {
        exit('未知的錯誤');
    }
} else {
    exit('Bad Request');
}

我有用本地端測試
http://localhost:9002//w01_line_notify.php

還是一樣!!!

淺水員 iT邦大師 6 級 ‧ 2021-02-22 00:20:12 檢舉

AUTH_PAGE_URL 要跟 Line 那邊填寫的一樣
所以每次改 url ,要記得去 line 後台那邊修改

//所註冊服務的 callback URL(由 authLineToken.php 處理)
const AUTH_PAGE_URL='http://localhost/authLineToken.php';

其他資訊也確認一下吧?

淺水員 iT邦大師 6 級 ‧ 2021-02-22 00:26:05 檢舉

就是當時填寫的這個,跟 AUTH_PAGE_URL 要相同
https://ithelp.ithome.com.tw/upload/images/20210222/20112943qJ8ljCw4gx.png

這邊的 callback URL
跟LINE那邊是一樣的

<?php
//所註冊服務的 client id
const CLIENT_ID='X1zUzNSSqbJeokBalwdBmi';

//所註冊服務的 client secret
const CLIENT_SECRET='0h5PkTU6ZlymWE0soqXvTYxx8mkqfoEvur38XA3I2I5';

//所註冊服務的 callback URL(由 authLineToken.php 處理)
const AUTH_PAGE_URL='https://ble.com.tw/Iot360/w00_line_notify_call.php';

?>

https://ithelp.ithome.com.tw/upload/images/20210222/20013294yYMlnjYvqI.png

如果設錯的話,會出現
`Bad Request: redirect_uri is not matched with registered URI``

callback URL這部分,我設定正確!!!

淺水員 iT邦大師 6 級 ‧ 2021-02-22 20:58:51 檢舉

昨天我是用 PHP7.4 + apache2.4
我剛剛改用 PHP5.6 + apache2.4,複製你後來改的程式碼,有跑出來 access_token。
所以還是不知道為什麼

淺水員 iT邦大師 6 級 ‧ 2021-02-22 21:22:06 檢舉

另外你最原始的程式(7-zip內的) v00_line_notify_call.php
82~83行是不是要這樣?

$line_token = $response['access_token'];
echo "line_token: $line_token";

我測試一樣可以取得 token

淺水員 iT邦大師 6 級 ‧ 2021-02-23 17:19:18 檢舉

我只能提幾個想法

  1. 不知道你是不是用 big5,不過照理說英文數字部分,big5 跟 utf8 應該是相同的。
  2. 非必要的話,php的結束符號我會省略,因為不小心就會開始送出 「空白」,導致要送 header 可能會發生問題。不過這應該也跟 curl 無關,所以我前面沒特別提出來。
  3. 找個方法確認一下 curl 送出的東西是正常的,也許可以寫一個 recive.php,這個程式會把送來的請求詳細的紀錄下來。然後把原本要送給 line api 的內容先送給自己,看看內容有沒有問題。(這晚點我可以試著做看看)

1.我未指定編碼格式,英數應該不需要指定
2.php空白,這我確認過沒出現...
3.我確認過是抓取line給我的code
https://ble.com.tw/Iot360/w02_line_notify_call.php?code=gCR3odoPECXrW8uxeACGGu&state=NO_STATE

然後傳給它,才出錯的...

我打算發一封信給line客服 問原因

淺水員 iT邦大師 6 級 ‧ 2021-02-24 17:00:23 檢舉

我也想不到其他的了,不知道新開一個帳號能不能正常運作。
如果是的話就是帳號的問題了。

這個方法,我嘗試過,別人的帳號測試過了...

在3台服務器上測試.結果一樣...

line的問題,真奇妙

你應該沒有在postman的Authorization設定你的access token
Type請選擇 Bearer token
右側再貼上你的access token 發送應該就可以了

我已經知道原因了???原來我測試的幾個line帳號,
申請的Line Notify發行存取權杖(開發人員用) 數量太多了

我剛剛用一個新帳號去申請 就可以了....

淺水員 iT邦大師 6 級 ‧ 2021-03-16 21:21:30 檢舉

原來如此,謝謝分享

淺水員 你的程式也是正確的....我應該感謝你的熱心

我要發表回答

立即登入回答