ASP.NET MVC第013天_ASP.NET Identity使用筆記_註冊完後的郵件有效性確認
註冊完的使用者
通常網站上的操作是會發一個確認通知信
可能有驗證碼
一來是為了確認輸入的email有效性
二來也是再多一份身分有效性驗證
預設我們可以去觀察Identity自動幫我們建立好的資料表結構
就有規劃像是EmailConfirmed , PhoneNumberConfirmed等布林值欄位
就是要我們留意記得再多做這些真實身分認證
針對發信驗證部分
先研究一下UserManager本身封裝的結構
可以看到本身有支援除了Email驗證也包含簡訊的SMS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 | #region 組件 Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 // D:\SideProjects\AgricultureManagementSystem_Tmp\AgricultureManagementSystem\packages\Microsoft.AspNet.Identity.Core.2.2.3\lib\net45\Microsoft.AspNet.Identity.Core.dll #endregion using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Security.Claims; using System.Threading.Tasks; namespace Microsoft.AspNet.Identity { // // 摘要: // Exposes user related api which will automatically save changes to the UserStore // // 類型參數: // TUser: // // TKey: public class UserManager<TUser, TKey> : IDisposable where TUser : class, IUser<TKey> where TKey : IEquatable<TKey> { // // 摘要: // Constructor // // 參數: // store: // The IUserStore is responsible for commiting changes via the UpdateAsync/CreateAsync // methods public UserManager(IUserStore<TUser, TKey> store); // // 摘要: // Used to validate users before changes are saved public IIdentityValidator<TUser> UserValidator { get; set; } // // 摘要: // Used to validate passwords before persisting changes public IIdentityValidator<string> PasswordValidator { get; set; } // // 摘要: // Used to create claims identities from users public IClaimsIdentityFactory<TUser, TKey> ClaimsIdentityFactory { get; set; } // // 摘要: // Used to send email public IIdentityMessageService EmailService { get; set; } // // 摘要: // Used to send a sms message public IIdentityMessageService SmsService { get; set; } // // 摘要: // Used for generating reset password and confirmation tokens public IUserTokenProvider<TUser, TKey> UserTokenProvider { get; set; } // // 摘要: // If true, will enable user lockout when users are created public bool UserLockoutEnabledByDefault { get; set; } // // 摘要: // Number of access attempts allowed before a user is locked out (if lockout is // enabled) public int MaxFailedAccessAttemptsBeforeLockout { get; set; } // // 摘要: // Default amount of time that a user is locked out for after MaxFailedAccessAttemptsBeforeLockout // is reached public TimeSpan DefaultAccountLockoutTimeSpan { get; set; } // // 摘要: // Returns true if the store is an IUserTwoFactorStore public virtual bool SupportsUserTwoFactor { get; } // // 摘要: // Returns true if the store is an IUserPasswordStore public virtual bool SupportsUserPassword { get; } // // 摘要: // Returns true if the store is an IUserSecurityStore public virtual bool SupportsUserSecurityStamp { get; } // // 摘要: // Returns true if the store is an IUserRoleStore public virtual bool SupportsUserRole { get; } // // 摘要: // Returns true if the store is an IUserLoginStore public virtual bool SupportsUserLogin { get; } // // 摘要: // Returns true if the store is an IUserEmailStore public virtual bool SupportsUserEmail { get; } // // 摘要: // Returns true if the store is an IUserPhoneNumberStore public virtual bool SupportsUserPhoneNumber { get; } // // 摘要: // Returns true if the store is an IUserClaimStore public virtual bool SupportsUserClaim { get; } // // 摘要: // Returns true if the store is an IUserLockoutStore public virtual bool SupportsUserLockout { get; } // // 摘要: // Returns true if the store is an IQueryableUserStore public virtual bool SupportsQueryableUsers { get; } // // 摘要: // Used to hash/verify passwords public IPasswordHasher PasswordHasher { get; set; } // // 摘要: // Returns an IQueryable of users if the store is an IQueryableUserStore public virtual IQueryable<TUser> Users { get; } // // 摘要: // Maps the registered two-factor authentication providers for users by their id public IDictionary<string, IUserTokenProvider<TUser, TKey>> TwoFactorProviders { get; } // // 摘要: // Persistence abstraction that the UserManager operates against protected internal IUserStore<TUser, TKey> Store { get; set; } // // 摘要: // Increments the access failed count for the user and if the failed access account // is greater than or equal to the MaxFailedAccessAttempsBeforeLockout, the user // will be locked out for the next DefaultAccountLockoutTimeSpan and the AccessFailedCount // will be reset to 0. This is used for locking out the user account. // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<AccessFailedAsync>d__144))] public virtual Task<IdentityResult> AccessFailedAsync(TKey userId); // // 摘要: // Add a user claim // // 參數: // userId: // // claim: [AsyncStateMachine(typeof(UserManager<,>.<AddClaimAsync>d__101))] public virtual Task<IdentityResult> AddClaimAsync(TKey userId, Claim claim); // // 摘要: // Associate a login with a user // // 參數: // userId: // // login: [AsyncStateMachine(typeof(UserManager<,>.<AddLoginAsync>d__98))] public virtual Task<IdentityResult> AddLoginAsync(TKey userId, UserLoginInfo login); // // 摘要: // Add a user password only if one does not already exist // // 參數: // userId: // // password: [AsyncStateMachine(typeof(UserManager<,>.<AddPasswordAsync>d__83))] public virtual Task<IdentityResult> AddPasswordAsync(TKey userId, string password); // // 摘要: // Add a user to a role // // 參數: // userId: // // role: [AsyncStateMachine(typeof(UserManager<,>.<AddToRoleAsync>d__105))] public virtual Task<IdentityResult> AddToRoleAsync(TKey userId, string role); // // 摘要: // Method to add user to multiple roles // // 參數: // userId: // user id // // roles: // list of role names [AsyncStateMachine(typeof(UserManager<,>.<AddToRolesAsync>d__106))] public virtual Task<IdentityResult> AddToRolesAsync(TKey userId, params string[] roles); // // 摘要: // Change a user password // // 參數: // userId: // // currentPassword: // // newPassword: [AsyncStateMachine(typeof(UserManager<,>.<ChangePasswordAsync>d__84))] public virtual Task<IdentityResult> ChangePasswordAsync(TKey userId, string currentPassword, string newPassword); // // 摘要: // Set a user's phoneNumber with the verification token // // 參數: // userId: // // phoneNumber: // // token: [AsyncStateMachine(typeof(UserManager<,>.<ChangePhoneNumberAsync>d__121))] public virtual Task<IdentityResult> ChangePhoneNumberAsync(TKey userId, string phoneNumber, string token); // // 摘要: // Returns true if the password is valid for the user // // 參數: // user: // // password: [AsyncStateMachine(typeof(UserManager<,>.<CheckPasswordAsync>d__81))] public virtual Task<bool> CheckPasswordAsync(TUser user, string password); // // 摘要: // Confirm the user's email with confirmation token // // 參數: // userId: // // token: [AsyncStateMachine(typeof(UserManager<,>.<ConfirmEmailAsync>d__116))] public virtual Task<IdentityResult> ConfirmEmailAsync(TKey userId, string token); // // 摘要: // Create a user with the given password // // 參數: // user: // // password: [AsyncStateMachine(typeof(UserManager<,>.<CreateAsync>d__79))] public virtual Task<IdentityResult> CreateAsync(TUser user, string password); // // 摘要: // Create a user with no password // // 參數: // user: [AsyncStateMachine(typeof(UserManager<,>.<CreateAsync>d__73))] public virtual Task<IdentityResult> CreateAsync(TUser user); // // 摘要: // Creates a ClaimsIdentity representing the user // // 參數: // user: // // authenticationType: public virtual Task<ClaimsIdentity> CreateIdentityAsync(TUser user, string authenticationType); // // 摘要: // Delete a user // // 參數: // user: [AsyncStateMachine(typeof(UserManager<,>.<DeleteAsync>d__75))] public virtual Task<IdentityResult> DeleteAsync(TUser user); // // 摘要: // Dispose this object public void Dispose(); // // 摘要: // Return a user with the specified username and password or null if there is no // match. // // 參數: // userName: // // password: [AsyncStateMachine(typeof(UserManager<,>.<FindAsync>d__80))] public virtual Task<TUser> FindAsync(string userName, string password); // // 摘要: // Returns the user associated with this login public virtual Task<TUser> FindAsync(UserLoginInfo login); // // 摘要: // Find a user by his email // // 參數: // email: public virtual Task<TUser> FindByEmailAsync(string email); // // 摘要: // Find a user by id // // 參數: // userId: public virtual Task<TUser> FindByIdAsync(TKey userId); // // 摘要: // Find a user by user name // // 參數: // userName: public virtual Task<TUser> FindByNameAsync(string userName); // // 摘要: // Generate a code that the user can use to change their phone number to a specific // number // // 參數: // userId: // // phoneNumber: [AsyncStateMachine(typeof(UserManager<,>.<GenerateChangePhoneNumberTokenAsync>d__124))] public virtual Task<string> GenerateChangePhoneNumberTokenAsync(TKey userId, string phoneNumber); // // 摘要: // Get the email confirmation token for the user // // 參數: // userId: public virtual Task<string> GenerateEmailConfirmationTokenAsync(TKey userId); // // 摘要: // Generate a password reset token for the user using the UserTokenProvider // // 參數: // userId: public virtual Task<string> GeneratePasswordResetTokenAsync(TKey userId); // // 摘要: // Get a token for a specific two factor provider // // 參數: // userId: // // twoFactorProvider: [AsyncStateMachine(typeof(UserManager<,>.<GenerateTwoFactorTokenAsync>d__131))] public virtual Task<string> GenerateTwoFactorTokenAsync(TKey userId, string twoFactorProvider); // // 摘要: // Get a user token for a specific purpose // // 參數: // purpose: // // userId: [AsyncStateMachine(typeof(UserManager<,>.<GenerateUserTokenAsync>d__127))] public virtual Task<string> GenerateUserTokenAsync(string purpose, TKey userId); // // 摘要: // Returns the number of failed access attempts for the user // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetAccessFailedCountAsync>d__146))] public virtual Task<int> GetAccessFailedCountAsync(TKey userId); // // 摘要: // Get a users's claims // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetClaimsAsync>d__103))] public virtual Task<IList<Claim>> GetClaimsAsync(TKey userId); // // 摘要: // Get a user's email // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetEmailAsync>d__112))] public virtual Task<string> GetEmailAsync(TKey userId); // // 摘要: // Returns whether lockout is enabled for the user // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetLockoutEnabledAsync>d__141))] public virtual Task<bool> GetLockoutEnabledAsync(TKey userId); // // 摘要: // Returns when the user is no longer locked out, dates in the past are considered // as not being locked out // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetLockoutEndDateAsync>d__142))] public virtual Task<DateTimeOffset> GetLockoutEndDateAsync(TKey userId); // // 摘要: // Gets the logins for a user. // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetLoginsAsync>d__99))] public virtual Task<IList<UserLoginInfo>> GetLoginsAsync(TKey userId); // // 摘要: // Get a user's phoneNumber // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetPhoneNumberAsync>d__119))] public virtual Task<string> GetPhoneNumberAsync(TKey userId); // // 摘要: // Returns the roles for the user // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetRolesAsync>d__109))] public virtual Task<IList<string>> GetRolesAsync(TKey userId); // // 摘要: // Returns the current security stamp for a user // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetSecurityStampAsync>d__89))] public virtual Task<string> GetSecurityStampAsync(TKey userId); // // 摘要: // Get whether two factor authentication is enabled for a user // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetTwoFactorEnabledAsync>d__134))] public virtual Task<bool> GetTwoFactorEnabledAsync(TKey userId); // // 摘要: // Returns a list of valid two factor providers for a user // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<GetValidTwoFactorProvidersAsync>d__129))] public virtual Task<IList<string>> GetValidTwoFactorProvidersAsync(TKey userId); // // 摘要: // Returns true if the user has a password // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<HasPasswordAsync>d__82))] public virtual Task<bool> HasPasswordAsync(TKey userId); // // 摘要: // Returns true if the user's email has been confirmed // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<IsEmailConfirmedAsync>d__117))] public virtual Task<bool> IsEmailConfirmedAsync(TKey userId); // // 摘要: // Returns true if the user is in the specified role // // 參數: // userId: // // role: [AsyncStateMachine(typeof(UserManager<,>.<IsInRoleAsync>d__110))] public virtual Task<bool> IsInRoleAsync(TKey userId, string role); // // 摘要: // Returns true if the user is locked out // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<IsLockedOutAsync>d__139))] public virtual Task<bool> IsLockedOutAsync(TKey userId); // // 摘要: // Returns true if the user's phone number has been confirmed // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<IsPhoneNumberConfirmedAsync>d__122))] public virtual Task<bool> IsPhoneNumberConfirmedAsync(TKey userId); // // 摘要: // Notify a user with a token using a specific two-factor authentication provider's // Notify method // // 參數: // userId: // // twoFactorProvider: // // token: [AsyncStateMachine(typeof(UserManager<,>.<NotifyTwoFactorTokenAsync>d__132))] public virtual Task<IdentityResult> NotifyTwoFactorTokenAsync(TKey userId, string twoFactorProvider, string token); // // 摘要: // Register a two factor authentication provider with the TwoFactorProviders mapping // // 參數: // twoFactorProvider: // // provider: public virtual void RegisterTwoFactorProvider(string twoFactorProvider, IUserTokenProvider<TUser, TKey> provider); // // 摘要: // Remove a user claim // // 參數: // userId: // // claim: [AsyncStateMachine(typeof(UserManager<,>.<RemoveClaimAsync>d__102))] public virtual Task<IdentityResult> RemoveClaimAsync(TKey userId, Claim claim); // // 摘要: // Remove a user from a role. // // 參數: // userId: // // role: [AsyncStateMachine(typeof(UserManager<,>.<RemoveFromRoleAsync>d__108))] public virtual Task<IdentityResult> RemoveFromRoleAsync(TKey userId, string role); // // 摘要: // Remove user from multiple roles // // 參數: // userId: // user id // // roles: // list of role names [AsyncStateMachine(typeof(UserManager<,>.<RemoveFromRolesAsync>d__107))] public virtual Task<IdentityResult> RemoveFromRolesAsync(TKey userId, params string[] roles); // // 摘要: // Remove a user login // // 參數: // userId: // // login: [AsyncStateMachine(typeof(UserManager<,>.<RemoveLoginAsync>d__97))] public virtual Task<IdentityResult> RemoveLoginAsync(TKey userId, UserLoginInfo login); // // 摘要: // Remove a user's password // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<RemovePasswordAsync>d__85))] public virtual Task<IdentityResult> RemovePasswordAsync(TKey userId); // // 摘要: // Resets the access failed count for the user to 0 // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<ResetAccessFailedCountAsync>d__145))] public virtual Task<IdentityResult> ResetAccessFailedCountAsync(TKey userId); // // 摘要: // Reset a user's password using a reset password token // // 參數: // userId: // // token: // // newPassword: [AsyncStateMachine(typeof(UserManager<,>.<ResetPasswordAsync>d__92))] public virtual Task<IdentityResult> ResetPasswordAsync(TKey userId, string token, string newPassword); // // 摘要: // Send an email to the user // // 參數: // userId: // // subject: // // body: [AsyncStateMachine(typeof(UserManager<,>.<SendEmailAsync>d__136))] public virtual Task SendEmailAsync(TKey userId, string subject, string body); // // 摘要: // Send a user a sms message // // 參數: // userId: // // message: [AsyncStateMachine(typeof(UserManager<,>.<SendSmsAsync>d__137))] public virtual Task SendSmsAsync(TKey userId, string message); // // 摘要: // Set a user's email // // 參數: // userId: // // email: [AsyncStateMachine(typeof(UserManager<,>.<SetEmailAsync>d__113))] public virtual Task<IdentityResult> SetEmailAsync(TKey userId, string email); // // 摘要: // Sets whether lockout is enabled for this user // // 參數: // userId: // // enabled: [AsyncStateMachine(typeof(UserManager<,>.<SetLockoutEnabledAsync>d__140))] public virtual Task<IdentityResult> SetLockoutEnabledAsync(TKey userId, bool enabled); // // 摘要: // Sets the when a user lockout ends // // 參數: // userId: // // lockoutEnd: [AsyncStateMachine(typeof(UserManager<,>.<SetLockoutEndDateAsync>d__143))] public virtual Task<IdentityResult> SetLockoutEndDateAsync(TKey userId, DateTimeOffset lockoutEnd); // // 摘要: // Set a user's phoneNumber // // 參數: // userId: // // phoneNumber: [AsyncStateMachine(typeof(UserManager<,>.<SetPhoneNumberAsync>d__120))] public virtual Task<IdentityResult> SetPhoneNumberAsync(TKey userId, string phoneNumber); // // 摘要: // Set whether a user has two factor authentication enabled // // 參數: // userId: // // enabled: [AsyncStateMachine(typeof(UserManager<,>.<SetTwoFactorEnabledAsync>d__135))] public virtual Task<IdentityResult> SetTwoFactorEnabledAsync(TKey userId, bool enabled); // // 摘要: // Update a user // // 參數: // user: [AsyncStateMachine(typeof(UserManager<,>.<UpdateAsync>d__74))] public virtual Task<IdentityResult> UpdateAsync(TUser user); // // 摘要: // Generate a new security stamp for a user, used for SignOutEverywhere functionality // // 參數: // userId: [AsyncStateMachine(typeof(UserManager<,>.<UpdateSecurityStampAsync>d__90))] public virtual Task<IdentityResult> UpdateSecurityStampAsync(TKey userId); // // 摘要: // Verify the code is valid for a specific user and for a specific phone number // // 參數: // userId: // // token: // // phoneNumber: [AsyncStateMachine(typeof(UserManager<,>.<VerifyChangePhoneNumberTokenAsync>d__125))] public virtual Task<bool> VerifyChangePhoneNumberTokenAsync(TKey userId, string token, string phoneNumber); // // 摘要: // Verify a two factor token with the specified provider // // 參數: // userId: // // twoFactorProvider: // // token: [AsyncStateMachine(typeof(UserManager<,>.<VerifyTwoFactorTokenAsync>d__130))] public virtual Task<bool> VerifyTwoFactorTokenAsync(TKey userId, string twoFactorProvider, string token); // // 摘要: // Verify a user token with the specified purpose // // 參數: // userId: // // purpose: // // token: [AsyncStateMachine(typeof(UserManager<,>.<VerifyUserTokenAsync>d__126))] public virtual Task<bool> VerifyUserTokenAsync(TKey userId, string purpose, string token); // // 摘要: // When disposing, actually dipose the store // // 參數: // disposing: protected virtual void Dispose(bool disposing); [AsyncStateMachine(typeof(UserManager<,>.<UpdatePassword>d__86))] protected virtual Task<IdentityResult> UpdatePassword(IUserPasswordStore<TUser, TKey> passwordStore, TUser user, string newPassword); // // 摘要: // By default, retrieves the hashed password from the user store and calls PasswordHasher.VerifyHashPassword // // 參數: // store: // // user: // // password: [AsyncStateMachine(typeof(UserManager<,>.<VerifyPasswordAsync>d__87))] protected virtual Task<bool> VerifyPasswordAsync(IUserPasswordStore<TUser, TKey> store, TUser user, string password); } } |
IIdentityMessageService本身就訂好要實作的寄送方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #region 組件 Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 // D:\SideProjects\AgricultureManagementSystem_Tmp\AgricultureManagementSystem\packages\Microsoft.AspNet.Identity.Core.2.2.3\lib\net45\Microsoft.AspNet.Identity.Core.dll #endregion using System.Threading.Tasks; namespace Microsoft.AspNet.Identity { // // 摘要: // Expose a way to send messages (i.e. email/sms) public interface IIdentityMessageService { // // 摘要: // This method should send the message // // 參數: // message: Task SendAsync(IdentityMessage message); } } |
這邊傳入的 IdentityMessage型別就是Identity框架已經幫我們封裝好
支援手機簡訊跟郵件資訊的DTO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #region 組件 Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 // D:\SideProjects\AgricultureManagementSystem_Tmp\AgricultureManagementSystem\packages\Microsoft.AspNet.Identity.Core.2.2.3\lib\net45\Microsoft.AspNet.Identity.Core.dll #endregion namespace Microsoft.AspNet.Identity { // // 摘要: // Represents a message public class IdentityMessage { public IdentityMessage(); // // 摘要: // Destination, i.e. To email, or SMS phone number public virtual string Destination { get; set; } // // 摘要: // Subject public virtual string Subject { get; set; } // // 摘要: // Message contents public virtual string Body { get; set; } } } |
這裡準備好一個寄信公用Utility程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Mail; using System.Web; namespace AgricultureManagementSystem.Public { public class Common { public static bool SendMail(string smtpServer, int smtpPort, string password, string strFrom, string strTo, string strSubject, string strBody) { MailAddress mailFrom = new MailAddress(strFrom); MailAddress mailTo = new MailAddress(strTo); MailMessage mailMessage = new MailMessage(mailFrom, mailTo) { Subject = strSubject, Body=strBody, IsBodyHtml = true }; SmtpClient smtpClient = new SmtpClient() { Host = smtpServer, Port = smtpPort, UseDefaultCredentials = true, Credentials = new NetworkCredential(strFrom, password) }; smtpClient.Send(mailMessage); mailFrom = null; mailTo = null; smtpClient.Dispose(); mailMessage.Dispose(); return true; } } } |
在IdentityConfig.cs新增EmailService並於UserManager Create方法裡面進行註冊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | using AgricultureManagementSystem.Models; using AgricultureManagementSystem.Public; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using Microsoft.Owin.Security; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using System.Web; namespace AgricultureManagementSystem { public class UserManager : UserManager<User> { public UserManager(IUserStore<User> store) : base(store) { } public static UserManager Create(IdentityFactoryOptions<UserManager> options, IOwinContext context) { var manager = new UserManager(new UserStore<User>(context.Get<Models.IdentityDbContext>())); //manager.UserValidator = new UserValidator<User>(manager) //{ // AllowOnlyAlphanumericUserNames = false, // RequireUniqueEmail = true //}; manager.UserValidator = new CustomUserValidator(manager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; manager.EmailService = new EmailService(); var dataProtectionProvider = options.DataProtectionProvider; if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider<User>(dataProtectionProvider.Create("EmailConfirm")); } return manager; } } public class EmailService : IIdentityMessageService { //https://developers.google.com/gmail/imap/imap-smtp public Task SendAsync(IdentityMessage message) { Common.SendMail("smtp.gmail.com", 587, ConfigurationManager.AppSettings["MailPwd"], "chousml@gmail.com", message.Destination, message.Subject, message.Body); return Task.FromResult(0); } } } |
manager.EmailService = new EmailService();
這裡設置我們自建的EmailService class實體
而在IdentityFactoryOptions 中透過DataProtectionProvider
做發信配置到UserManager的過程
在註冊表單Post事件Add增加發註冊驗證信的程式
以及用戶點擊信件連結觸發驗證信箱的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Add(AddUserViewModel addUserViewModel) { if (ModelState.IsValid) { var user = new User { UserName = addUserViewModel.Account, Account = addUserViewModel.Account, Email = addUserViewModel.Email, Region = addUserViewModel.Region }; var result = await UserManager.CreateAsync(user, addUserViewModel.Password); if (result.Succeeded) { string verify_code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); //string verify_code_encode = HttpUtility.UrlEncode(verify_code); var verify_EmailUrl = Url.Action("ConfirmEmail", "Register", new { userId = user.Id, code = verify_code }, protocol: Request.Url.Scheme); await UserManager.SendEmailAsync(user.Id, "新註冊用戶信箱開通", "請點擊如下連結 <a href =\"" + verify_EmailUrl + "\">Here</a>來確認你的帳戶"); return RedirectToAction("Index", "Login"); } AddErrors(result); } //return RedirectToAction("Index", "Register", addUserViewModel); return View(addUserViewModel); } [HttpGet] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> ConfirmEmail(string userId, string code) { if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(code)) { return View("Error"); } var result = await UserManager.ConfirmEmailAsync(userId, code); return View(result.Succeeded ? "ConfirmEmail" : "Error"); } |
當成功驗證回傳後就會將AspNetUsers表中的
[EmailConfirmed]更新為true
在記得擴充兩個檢視顯示
錯誤警示的和信箱成功啟用的檢視
#################更新#################
針對Identity 若有去客自訂自己客製化額外跟DB查檢的部分若寫在自己覆寫的
要小心Identity本身封裝的method執行生命週期只要跑到
CreateAsync
UpdateAsync
ConfirmEmailAsync
.....
都會再跑進UserValidator包含自己overwrite的衍生Class中的
public override async Task<IdentityResult> ValidateAsync(User user)方法
#################更新#################
Ref:
[WEB API] Identity 寄Email驗證帳號和密碼規則
https://dotblogs.com.tw/kinanson/2015/05/13/151271
[WEB API]Identity 實現登入Token驗証
https://dotblogs.com.tw/kinanson/2015/05/17/151323
留言
張貼留言