リセットパスワード機能を実装する方法
あなたはnodejsとPostgreSQLとサーバー上でリセットパスワード機能を実装する方法を疑問に思ったことがありますか?
私はノードとmongodbでそれをする方法に関する多くの記事とチュートリアルを見つけました.
最初に、私たちは電子メールサービスを見つける必要があります、私は最初にnodemailerを試みました、そして、それは完全に私のローカル環境で働きます、しかし、生産で、私は私のGmailアカウントで若干のセキュリティ問題を得ていました.そういうわけで、私はsendgridで行くことに決めました.
クリエイトアSendGrid account , 電子メールAPI、統合ガイドに移動し、Web APIを選択し、ちょうどAPIキーを生成する指示に従ってください
依存関係のインストール
どのように我々のユーザーテーブルが見えるか見ましょう
私はデータベースと対話するためにKenexライブラリを使用しています
さあ、ルートを作ろう
すべてがOKであるならば、あなたは200のステータスを得なければなりません
Postman貼り付けのトークン
あなたは200のステータスコードを取得する必要があります
完全な例コードで私のreposのうちの1つへのリンクは、ここにありますrepo
私はあなたがこの助けを見つける願っています!あなたが質問をするならば、私にコメントで知らせさせてください.
私は同じ機能を追加する予定ですが、REDISを使用してデータベースの代わりにテンポラリトークンを保存します.
私はノードとmongodbでそれをする方法に関する多くの記事とチュートリアルを見つけました.
最初に、私たちは電子メールサービスを見つける必要があります、私は最初にnodemailerを試みました、そして、それは完全に私のローカル環境で働きます、しかし、生産で、私は私のGmailアカウントで若干のセキュリティ問題を得ていました.そういうわけで、私はsendgridで行くことに決めました.
クリエイトアSendGrid account , 電子メールAPI、統合ガイドに移動し、Web APIを選択し、ちょうどAPIキーを生成する指示に従ってください
依存関係のインストール
npm install --save @sendgrid/mail
npm install express bcryptjs jsonwebtoken knex
APIキーを作成しました.envファイルをキーを格納します.どのように我々のユーザーテーブルが見えるか見ましょう
私はデータベースと対話するためにKenexライブラリを使用しています
table.increments();
table.string("email", 128).unique().notNullable();
table.string("password", 128).notNullable();
table.string("resetLink", 255);
ご覧の通り定義します"resetLink"
オプションです.さあ、ルートを作ろう
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const sgMail = require('@sendgrid/mail');
const route = express.Router();
// bring env variables into file
const sendGridKey = process.env.SENDGRID_KEY;
const resetSecret = process.env.RESET_SECRET;
route.patch('/forgot-password', async (req, res) => {
const { email } = req.body;
try {
// look for email in database
const [user] = await filterBy({ email });
// if there is no user send back an error
if(!user) {
res.status(404).json({ error: "Invalid email" });
} else {
// otherwise we need to create a temporary token that expires in 10 mins
const resetLink = jwt.sign({ user: user.email },
resetSecret, { expiresIn: '10m' });
// update resetLink property to be the temporary token and then send email
await update(user.id, { resetLink });
// we'll define this function below
sendEmail(user, resetLink);
res.status(200).json({ message: "Check your email"} );
}
} catch(error) {
res.status(500).json({ message: error.message });
}
}
新しい定義を定義しましょうPATCH
新しいパスワードを更新するルート
route.patch('/reset-password/:token', async (req, res) => {
// Get the token from params
const resetLink = req.params.token;
const newPassword = req.body;
// if there is a token we need to decoded and check for no errors
if(resetLink) {
jwt.verify(resetLink, resetPassword, (error, decodedToken) => {
if(error) {
res.status().json({ message: 'Incorrect token or expired' })
}
})
}
try {
// find user by the temporary token we stored earlier
const [user] = await filterBy({ resetLink });
// if there is no user, send back an error
if(!user) {
res.status(400).json({ message: 'We could not find a match for this link' });
}
// otherwise we need to hash the new password before saving it in the database
const hashPassword = bcrypt.hashSync(newPassword.password, 8);
newPassword.password = hashPassword;
// update user credentials and remove the temporary link from database before saving
const updatedCredentials = {
password: newPassword.password,
resetLink: null
}
await update(user.id, updatedCredentials);
res.status(200).json({ message: 'Password updated' });
} catch (error) {
res.status(500).json({ message: error.message });
}
})
この場合、データベースと対話するために使用している関数も定義しましょうfindBy() and update()
// I'm using knex to interact with the database here
// but all is doing is looking into 'users' table and filtering the data by the filter parameter
function filterBy(filter) {
return db('users').where(filter);
}
// same here, looking into 'users' table by 'id' and then updating the values
function update(id, changes) {
return db('users').where({ id }).update(changes);
}
定義しましょうsendEmail
機能function sendEmail(user, token) {
sgMail.setApiKey(sendGridKey);
const msg = {
to: user.email,
from: "", // your email
subject: "Reset password requested",
html: `
<a href="${clientURL}/reset-password/${token}">${token}</a>
`
// I'm only going to use an (a tag) to make this easier to
// understand but feel free to add any email templates
// in the `html` property
};
sgMail.send(msg)
.then(() => {
console.log("Email sent");
}).catch((error) => {
console.error(error);
})
}
今、私たちがそれをテストするために郵便配達人を使うつもりであるルートを作成したので、我々はAを作る必要がありますPATCH
リクエストすべてがOKであるならば、あなたは200のステータスを得なければなりません
Postman貼り付けのトークン
url/auth/reset-password/:token
下記の例を参照あなたは200のステータスコードを取得する必要があります
Password update
メッセージ完全な例コードで私のreposのうちの1つへのリンクは、ここにありますrepo
私はあなたがこの助けを見つける願っています!あなたが質問をするならば、私にコメントで知らせさせてください.
私は同じ機能を追加する予定ですが、REDISを使用してデータベースの代わりにテンポラリトークンを保存します.
Reference
この問題について(リセットパスワード機能を実装する方法), 我々は、より多くの情報をここで見つけました https://dev.to/anthonyamaro15/how-to-implement-reset-password-functionality-with-node-postgresql-knex-n8aテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol