建立完整的會員 Email 驗證與忘記密碼流程,含資料表結構、觸發器自動重置驗證狀態、請求處理預存程序、驗證/重設密碼預存程序,前後端分工明確。
ALTER TABLE dbo.Users ADD
Email VARCHAR(100) NULL,
IsVerify BIT NOT NULL DEFAULT(0);
CREATE TABLE dbo.RequestActionType (
Type NCHAR(2) NOT NULL PRIMARY KEY,
Description NVARCHAR(30) NULL
);
INSERT INTO dbo.RequestActionType VALUES
('V', N'驗證 Email 有效性'),
('C', N'使用者變更密碼');
CREATE TABLE dbo.UserRequestAction (
Type NCHAR(2) NOT NULL FOREIGN KEY REFERENCES RequestActionType(Type),
Token UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID(),
Account NVARCHAR(30) NOT NULL,
Email NVARCHAR(150) NOT NULL,
Expire DATETIME NOT NULL DEFAULT DATEADD(DAY, 1, CURRENT_TIMESTAMP)
);
CREATE TRIGGER tri_Users_Update ON dbo.Users FOR UPDATE AS
DECLARE @newEmail VARCHAR(100), @oldEmail VARCHAR(100), @account NVARCHAR(20), @isVerify BIT
SELECT @newEmail = Email FROM INSERTED
SELECT @account = U_nbr, @oldEmail = Email, @isVerify = IsVerify FROM DELETED
IF @isVerify = 1 AND (LEN(ISNULL(@newEmail,'')) = 0 OR @newEmail <> @oldEmail)
UPDATE dbo.Users SET IsVerify = 0 WHERE U_nbr = @account
CREATE PROCEDURE usp_UserRequestAction_Request
@Type NCHAR(2), @U_nbr NVARCHAR(20)
AS
IF NOT EXISTS(SELECT 1 FROM dbo.Users WHERE U_nbr = @U_nbr)
RAISERROR(N'帳號不存在', 16, 1)
DECLARE @Email NVARCHAR(100)
SELECT @Email = Email FROM dbo.Users WHERE U_nbr = @U_nbr
IF EXISTS(SELECT 1 FROM dbo.UserRequestAction
WHERE Type = @Type AND Account = @U_nbr AND Email = @Email)
UPDATE dbo.UserRequestAction
SET Token = NEWID(), Expire = DATEADD(DAY, 1, CURRENT_TIMESTAMP)
WHERE Type = @Type AND Account = @U_nbr AND Email = @Email
ELSE
INSERT INTO dbo.UserRequestAction(Type, Account, Email)
VALUES (@Type, @U_nbr, @Email)
CREATE PROCEDURE usp_Users_UpdateIsVerifyField @token NVARCHAR(36) AS
IF EXISTS(SELECT 1 FROM dbo.UserRequestAction
WHERE Token = @token AND Expire >= CURRENT_TIMESTAMP)
BEGIN
DECLARE @account NVARCHAR(30)
SELECT @account = Account FROM dbo.UserRequestAction WHERE Token = @token
UPDATE dbo.Users SET IsVerify = 1 WHERE U_nbr = @account
UPDATE dbo.UserRequestAction SET Expire = DATEADD(DAY, -1, CURRENT_TIMESTAMP) WHERE Token = @token
END
CREATE PROCEDURE usp_Users_ResetPassword @token NVARCHAR(36), @Password NVARCHAR(100) AS
IF EXISTS(SELECT 1 FROM dbo.UserRequestAction
WHERE Token = @token AND Expire >= CURRENT_TIMESTAMP)
BEGIN
DECLARE @account NVARCHAR(30), @pwd VARBINARY(MAX)
SELECT @account = Account FROM dbo.UserRequestAction WHERE Token = @token
SET @pwd = ENCRYPTBYPASSPHRASE('insus#sec!%y', @Password)
UPDATE dbo.Users SET Pwd = @pwd WHERE U_nbr = @account
UPDATE dbo.UserRequestAction SET Expire = DATEADD(DAY, -1, CURRENT_TIMESTAMP) WHERE Token = @token
END
ELSE
RAISERROR(N'連結失效或已過期', 16, 1)
usp_UserRequestAction_Request 'V', @U_nbr → 寄送含 Token 連結信件usp_UserRequestAction_Request 'C', @U_nbr → 寄送重設連結Expire 設為過期,防重複使用NEWID() 或 CRYPT_GEN_RANDOM(32) 產生高熵值HASHBYTES('SHA2_256', salt + pwd)),勿用可逆加密此架構清晰分離資料層邏輯,前端僅負責流程導向與介面呈現,擴充性與維護性俱佳。