Twitter oauth1.0a 筆記
其實本來是想要試用Twitter API 2.0
的,但是要開啟新專案的時候被提示要先進行電話認證,所以只好先回來寫舊版本的筆記。
之所以舊版本不用電話認證的原因是在需要進行認證前就申請過了。
首先要去開發者後台把需要的key
和secret
複製出來,接著建立個setting.json
把它們放進去:
{
"key" : "",
"secret" : "",
"callback" : "http://127.0.0.1:3000/twitter/callback"
}
callback
的值會是晚點會建立的API
位置,路徑基本上應該要跟後台的設定一樣。
然後準備好package.json
:
{
"name": "example-twitter-oauth10a",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"express": "^4.18.1",
"express-session": "^1.17.3",
"oauth": "^0.9.15",
"twitter": "^1.7.1"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
接著就是index.js
了:
const setting = require('./setting.json'); // key , secret , callback
const oauth = require('oauth');
const oa = new oauth.OAuth(
'https://twitter.com/oauth/request_token',
'https://twitter.com/oauth/access_token',
setting.key,
setting.secret,
'1.0a',
setting.callback,
'HMAC-SHA1');
////
const express = require('express');
const session = require('express-session');
const secret = 'TEST_twitter_OAUTH_1.0a';
const app = express();
////
app.use(session({ secret }));
app.listen(3000, () => console.log('server port: 3000'));
////
app.get('/', (req, res) => {
res.send(`<html><head></head><body><a href="/twitter/auth">login</a></body></html>`);
})
app.get('/done', (req, res) => {
let at = req.session.oauthAccessToken;
res.send(`<html><head></head><body><h1>Access token</h1><p>${at}</p></body></html>`);
})
app.get('/twitter/auth', async (req, res) => {
const method = 'authenticate';
const { requestToken, requestTokenSecret } = await getRequestToken();
req.session = req.session || {};
req.session.requestToken = requestToken;
req.session.requestTokenSecret = requestTokenSecret;
const authUrl = `https://api.twitter.com/oauth/${method}?oauth_token=${requestToken}`;
console.log(`redirect to: ${authUrl}`);
res.redirect(authUrl);
})
app.get('/twitter/callback', async (req, res) => {
const { requestToken, requestTokenSecret } = req.session;
const { oauth_verifier: verifier } = req.query;
const { accessToken, accessTokenSecret } = await getAccessToken(requestToken, requestTokenSecret, verifier);
req.session.oauthAccessToken = accessToken;
console.log(`accessToken: ${accessToken} , accessTokenSecret: ${accessTokenSecret}`);
//sendTweet(accessToken,accessTokenSecret , 'test it.');
req.session.save(() => {
res.redirect('/done');
});
})
////
async function getRequestToken() {
return new Promise((resolve, reject) => {
oa.getOAuthRequestToken(
(error, requestToken, requestTokenSecret) => {
return error
? reject(new Error('getRequestToken failed'))
: resolve({ requestToken, requestTokenSecret });
})
})
}
async function getAccessToken(requestToken, requestTokenSecret, verifier) {
return new Promise((resolve, reject) => {
oa.getOAuthAccessToken(
requestToken,
requestTokenSecret,
verifier,
(error, accessToken, accessTokenSecret) => {
return error
? reject(new Error('getAccessToken failed'))
: resolve({ accessToken, accessTokenSecret });
})
})
}
function sendTweet(accessToken, accessTokenSecret, status) {
const Twitter = require('twitter');
const twi = new Twitter({
'consumer_key': setting.key,
'consumer_secret': setting.secret,
'access_token_key': accessToken,
'access_token_secret': accessTokenSecret
});
const data = {
status
};
twi.post('statuses/update', data, (error) => {
if (error) {
console.log(error);
} else {
console.log('tweet send.')
}
})
}
這邊寫了四支HTTP GET API
:
- /
首頁只有一個超連結,點擊後就進行認證。
- /done
流程跑完取得token
後會轉到該頁面並印出token
。
正常不應該把它印出來,單純只是因為是本機測試為了方便。
- /twitter/auth
首頁的超連結會呼叫該API
,取得request token
後會轉至twitter
官方確認頁面讓使用者確認。
- /twitter/callback
使用者點選確認連結後,twitter
就會重導向到這支API
來。
最後取得到需要的token
放到session
完就轉到/done
頁面顯示。
拿到使用者的token
後就可以用它們來呼叫twitter api
了。
最後補上dockerfile
:
FROM node:18-alpine
RUN apk add --no-cache \
nodejs
WORKDIR /app
COPY [ "package.json" , "index.js" , "setting.json" , "/app/" ]
RUN npm install
RUN npm install -g nodemon
EXPOSE 3000
CMD [ "nodemon", "index.js" ]
產生image
:
docker build -t example-twitter-oauth . --no-cache
最後執行:
docker run -itd -p 3000:3000 example-twitter-oauth
最後,到底要不要跑電話認證呢?其實也沒什麼,但就是有點抗拒啊⋯⋯
Read other posts