관리 메뉴

웹개발자의 기지개

[asp.net core MVC] 간단한 회원가입,로그인,로그아웃 (with DB, EntityFrameworkCore) 본문

ASP.NET/ASP.NET Core

[asp.net core MVC] 간단한 회원가입,로그인,로그아웃 (with DB, EntityFrameworkCore)

http://portfolio.wonpaper.net 2020. 5. 16. 18:03

asp.net MVC Core3.1 버전으로 아주 간단히 회원가입, 로그인, 로그아웃 기능을 구현해 보았다.

 

DB : MS-SQL Express (64-bit)

Microsoft EntityFrameworkCore 패키지 

 

깃허브(Github) 에서 전체 소스를 올려놓았다.

https://github.com/wonpaper/ASPNetMVC_Core3-LoginFormWithBCryptInASPNETCoreMVC

 

wonpaper/ASPNetMVC_Core3-LoginFormWithBCryptInASPNETCoreMVC

회원가입,로그인,로그아웃-기본형. Contribute to wonpaper/ASPNetMVC_Core3-LoginFormWithBCryptInASPNETCoreMVC development by creating an account on GitHub.

github.com

 

회원가입 테이블 스크립트

CREATE TABLE [dbo].[Account](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Username] [varchar](50) NOT NULL,
	[Password] [varchar](80) NULL,
	[FullName] [nvarchar](50) NULL,
 CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

 

일단 실행 결과 화면이미지부터 확인해 보도록 하자.

초기 index페이지 화면

 

로그인 실패시 화면

 

정상 로그인 했을때

 

회원가입페이지 signup 페이지

 

우선 Nuget 패키지에서 관련 패키지 또한 설치해 놓자.

 

전체 솔루션 탐색기 화면

 

[ appsettings.json ] - DB 접속 json

1
2
3
4
5
{
  "ConnectionStrings": {
    "AppDb""Server=(localdb)\\MSSQLLocalDB;Database=myDB;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}
cs

 

[ /Models/Account.cs ] - Account 기본 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
 
namespace LoginFormWithBCryptInASPNETCoreMVC.Models
{
    public class Account
    {
        [Key]
        public int Id { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string FullName { get; set; }
    }
}
 
cs

 

[/Models/AppDbContext.cs] - DBContext 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
 
namespace LoginFormWithBCryptInASPNETCoreMVC.Models
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {
 
        }
 
        // Account 회원 Set
        public DbSet<Account> Account { get; set; }
    }
}
cs

 

 

[ Startup.cs ] - 솔루션 환경 설정 관련

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LoginFormWithBCryptInASPNETCoreMVC.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
 
namespace LoginFormWithBCryptInASPNETCoreMVC
{
    public class Startup
    {
        private IConfiguration config = null;
        public Startup(IConfiguration config)
        {
            this.config = config;
        }
 
        public void ConfigureServices(IServiceCollection services)
        {
            // 세션 추가
            services.AddSession();
            services.AddControllersWithViews();
 
            // DB Context 추가
            services.AddDbContext<AppDbContext>(options => options.UseSqlServer(this.config.GetConnectionString("AppDb")));
 
        }
 
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
 
            app.UseStaticFiles();
            app.UseRouting();
 
            // 세션사용
            app.UseSession();
 
            /*
                        app.UseEndpoints(endpoints =>
                        {
                            endpoints.MapGet("/", async context =>
                            {
                                await context.Response.WriteAsync("Hello World!");
                            });
                        });
            */
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Account}/{action=Index}/{id?}"
                );
            });
        }
    }
}
cs

 

[ /Controllers/AccountController.cs ] - Control 관련 매니저 클래스

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LoginFormWithBCryptInASPNETCoreMVC.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
 
namespace LoginFormWithBCryptInASPNETCoreMVC.Controllers
{
    [Route("account")]
    public class AccountController : Controller
    {
        private AppDbContext db = null;
        public AccountController(AppDbContext db)
        {
            this.db = db;
        }
 
 
        [Route("")]
        [Route("index")]
        [Route("~/")]
        public IActionResult Index()
        {
            return View();
        }
 
        [HttpGet]
        [Route("signup")]
        public IActionResult SignUp()
        {
            return View("SignUp"new Account());
        }
 
        [HttpPost]
        [Route("signup")]
        public IActionResult SignUp(Account account)
        {
            account.Password = BCrypt.Net.BCrypt.HashPassword(account.Password);
            db.Account.Add(account);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
 
        [HttpPost]
        [Route("login")]
        public IActionResult Login(string username,string password)
        {
            var account = checkAccount(username, password);
            if (account == null)
            {
                ViewBag.error = "Invalid";
                return View("Index");
            } else
            {
                HttpContext.Session.SetString("username", username);
                return View("Success");
            }
            //return RedirectToAction("Index");
        }
 
        private Account checkAccount(string username, string password)
        {
            var account = db.Account.SingleOrDefault(a => a.Username.Equals(username));
            if (account != null)
            {
                if (BCrypt.Net.BCrypt.Verify(password,account.Password))
                {
                    return account;
                }
            }
            return null;
        }
 
        [Route("logout")]
        public IActionResult Logout()
        {
            HttpContext.Session.Remove("username");
            return RedirectToAction("Index");
        }
    }
}
cs

회원가입시 40라인이 비밀번호는 BCrypt 암호화해서 DB에 담긴다.

79라인처럼 username 키값의 세션을 단순 삭제할 수도 있지만, 현재 세션 전체 삭제하기는

HttpContext.Session.Clear(); 

하면된다.

 

이제부터는 View 관련 페이지 화면이다. AccountController.cs 소스와 같이 비교해서 보도록 하자.

 

[ /Views/Index.cshtml ]  - 초기페이지

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
@{ 
    Layout = null;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Index페이지</title>
</head>
<body>
    <h3>Login Page</h3>
    @ViewBag.error
    <form method="post" asp-controller="account" asp-action="login">
        <table>
            <tr>
                <td>Username</td>
                <td>
                    <input type="text" name="username" />
                </td>
            </tr>
            <tr>
                <td>Password</td>
                <td>
                    <input type="password" name="password" />
                </td>
            </tr>
            <tr>
                <td>&nbsp;</td>
                <td>
                    <input type="submit" value="Login" />
                    <br />
                    <a asp-controller="account" asp-action="signup">Sign Up</a>
                </td>
            </tr>
        </table>
    </form>
</body>
</html>
cs

 

[ /Views/SignUp.cshtml ] - 회원가입페이지

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
@{ 
    Layout = null;
}
@model LoginFormWithBCryptInASPNETCoreMVC.Models.Account
 
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>SignUp 페이지</title>
</head>
<body>
    <h3>SignUp Page</h3>
    <form method="post" asp-controller="account" asp-action="signup">
        <table>
            <tr>
                <td>Username</td>
                <td>
                    <input type="text" asp-for="Username" />
                </td>
            </tr>
            <tr>
                <td>Password</td>
                <td>
                    <input type="password" asp-for="Password" />
                </td>
            </tr>
            <tr>
                <td>Full Name</td>
                <td>
                    <input type="text" asp-for="FullName" />
                </td>
            </tr>
            <tr>
                <td>&nbsp;</td>
                <td>
                    <input type="submit" value="SignUp" />
                </td>
            </tr>
        </table>
    </form>
</body>
</html>
cs

 

[ /Views/Success.cshtml ] - 로그인 성공후 페이지화면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@{
    Layout = null;
}
@using Microsoft.AspNetCore.Http;
<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Success 페이지</title>
</head>
<body>
    Welcome @Context.Session.GetString("username")
    <br />
    <a asp-controller="account" asp-action="logout">Logout</a>
 
</body>
</html>
cs
Comments