(ASP.NET,C#)セッションを使う

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{

    services.AddControllersWithViews();

    // ----- Sessionを使用する -----
    services.AddSession(options => {
        options.Cookie.Name = "session";
    });

    // ・・・

}
// ユーザIDをセッションにセット
HttpContext.Session.SetString(SessionKey.UserId, UserId);

// ユーザIDをセッションにゲット
var userId = HttpContext.Session.GetString(SessionKey.UserId);

(C#)パスワードのハッシュ化

(C#)パスワードハッシュ化

ログインパスワードなど不可逆の文字列はハッシュを使う。

var salt = PasswordUtil.CreateSalt();
var hashedPassword = PasswordUtil.NewHashPassword(changePassword.Password, salt);
public class PasswordUtil
{
    /// <summary>
    /// ハッシュのサイズ
    /// </summary>
    private const int HashSize = 32;

    /// <summary>
    /// ソルトのサイズ
    /// </summary>
    private const int SaltSize = 32;

    /// <summary>
    /// ソルト生成時の反復回数
    /// </summary>
    private const int Iteration = 10000;

    /// <summary>
    /// DBに登録されているソルトを使ってパスワードをハッシュ化する
    /// </summary>
    /// <param name="password"></param>
    /// <returns></returns>
    public static string HashThePassword(string userId, string password, IDbConnection connection)
    {
        // ソルト取得
        var sql = SqlResource.get("Utility/GetSalt");
        var result = connection.Query<ValueModel>(sql, new { UserId = userId }).ToList();
        if (result.Count == 0)
        {
            return null;
        }
        string strSalt = (string)result[0].Value;

        // ハッシュ生成
        string strHash = NewHashPassword(password, strSalt);

        return strHash;
    }

    /// <summary>
    /// パスワードをハッシュ化する
    /// </summary>
    /// <param name="rawPassword"></param>
    /// <param name="salt"></param>
    /// <param name="size"></param>
    /// <returns></returns>
    public static string NewHashPassword(string rawPassword, string strSalt)
    {
        byte[] salt = Convert.FromBase64String(strSalt);

        using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(rawPassword, salt, Iteration))
        {
            byte[] hash = rfc2898DeriveBytes.GetBytes(HashSize);
            string strHash = Convert.ToBase64String(hash);
            return strHash;
        }
    }

    /// <summary>
    /// ランダムにソルトを作成する
    /// </summary>
    /// <param name="size"></param>
    /// <returns></returns>
    public static string CreateSalt()
    {
        using (var generator = RandomNumberGenerator.Create())
        {
            byte[] salt = new Byte[SaltSize];
            generator.GetBytes(salt);
            string strSalt = Convert.ToBase64String(salt);
            return strSalt;
        }
    }

}

(ASP.NET,C#)DI(Dependency Injection)する

Javaの Spring Boot の場合にDIするには @Autowired アノテーションを使ったが、
ASP.NETではコンポーネントの登録ソースをゴリっと書く。

DI登録

// Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    
    // 社員マスタ画面サービス
    services.AddScoped<IEmployeeMstService, EmployeeMstService>();

DBコネクションも登録する(できる)

// Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    // DBコネクション
    services.AddScoped<IDbConnection>(
        provider => new SqlConnection(
            Configuration.GetConnectionString("SQLServerConnection")));

注入する

どうやらコンポーネントを受け取る側のコンストラクタで受け取るようだ。

// EmployeeMstController

public EmployeeMstController(IEmployeeMstService service)
{
    this._service = service;
}
// IEmployeeMstService
public interface IEmployeeMstService
{

// EmployeeMstService
public class EmployeeMstService : IEmployeeMstService
    public EmployeeMstService(IDbConnection connection)
    {
        this._connection = connection;
    }

(ASP.NET,C#)NLogを使う

前回はLog4Netだけどどうやら今後NLogが主流になるようだ。
(↑ソースは忘れました)

NuGetでパッケージのインストール

  • NLog

  • NLog.Web.AspNetCore

nlog.config

プロジェクトROOTに nlog.config を配置する。
(↑NuGetパッケージのインストールを行ったら作成されたのかな?)

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Info"
      internalLogFile="internal-nlog.txt">
    <extensions>
        <add assembly="NLog.Web.AspNetCore" />
    </extensions>
    <targets async="true">
        <target xsi:type="File" name="debuglog"
                fileName="${aspnet-appbasepath}/logs/debug-${shortdate}.log"
                layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message}|url: ${aspnet-request-url:IncludeQueryString=true}" />
        <target xsi:type="File" name="infolog"
                fileName="${aspnet-appbasepath}/logs/info-${shortdate}.log"
                layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url:IncludeQueryString=true}" />
        <target xsi:type="File" name="errorlog"
                fileName="${aspnet-appbasepath}/logs/error-${shortdate}.log"
                layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|user: ${aspnet-user-identity} |url: ${aspnet-request-url:IncludeQueryString=true}|action: ${aspnet-request-form}" />
    </targets>
    <rules>
        <logger name="*" maxlevel="Debug" writeTo="debuglog" />
        <logger name="Microsoft.*" maxLevel="Info" final="true" />
        <logger name="*" levels="Error,Fatal,Warn" writeTo="errorlog" />
        <logger name="*" minlevel="Info" writeTo="infolog" />
    </rules>
</nlog>

ログ出力

private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
_logger.info("ロガーです!");

(ASP.NET, C#)Log4Netを使う

NuGet

  • ソリューションエクスプローラのプロジェクト直下の参照を右クリック

  • NuGetパッケージの管理

  • 参照タブのテキストボックスに「log4net」と入力

  • リストの中に「log4net」を選択、右ペインでインストールボタンを押下

設定ファイル

  • ソリューションエクスプローラのプロジェクト直下のPropertiesを開く

  • Properties/AssemblyInfo.cs

~(略)~
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4net.xml", Watch = true)]
  • Global.asax.cs
public class Global : HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        ~(略)~
        
        log4net.Config.XmlConfigurator.Configure();
    }
}
  • Web.config
<configuration>
  <configSections>
    <!-- log4netセクションのハンドラ設定 -->
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>

   ~(略)~
  <log4net>
    <!-- ===================================================================== -->
    <!--     ログ出力の対象レベルと出力先の設定                                -->
    <!-- ===================================================================== -->
    <root>
      <!-- ログのレベルを指定 -->
      <!-- ALL > DEBUG > INFO > WARN > ERROR > FATAL -->
      <level value="ALL"/>
      <!-- どのログ出力先を使用するか -->
      <appender-ref ref="RollingFileAppender"/>
    </root>
    <!-- ===================================================================== -->
    <!--                 ログ出力先の設定(アペンダーの設定)                    -->
    <!-- ===================================================================== -->
    <!-- ▼ファイル出力用[RollingFileAppender](日付や時刻の制約に基づいたログファイルの生成) -->
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <param name="Encoding" value="utf-8"/>
      <!-- ファイル名 -->
      <param name="File" value="logs\"/>
      <!-- 追記する場合true/上書きする場合false -->
      <param name="AppendToFile" value="true"/>
      <!-- 日付や時刻の制約によるログファイルの切替 -->
      <param name="RollingStyle" value="Date"/>
      <!-- 上から「毎月、毎週、毎日、半日、毎時、毎分」の設定(デフォルトは毎時) -->
      <param name="DatePattern" value='""yyyyMMdd".log"'/>
      <param name="StaticLogFileName" value="false"/>
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n"/>
      </layout>
    </appender>
  </log4net>

ログ出力

  • ログを出力したいCSファイル
    public partial class WebForm1 : System.Web.UI.Page
    {
        // ロガー
        private static readonly log4net.ILog logger = 
            log4net.LogManager.GetLogger(
                System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        /// <summary>
        /// 画面ロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            logger.Info("Debug message");
            logger.Info("Info message");
            logger.Warn("Warn message");
            logger.Error("Error message");
            logger.Fatal("Fatal message");

    ~(略)~

(Book)「know」を読みました。

f:id:project-masawa:20200422203320j:plain

野崎まど - know

野崎まど「know」を読みました。
だいぶ前に読み始めたのだけれど、なぜだか読み続けられなくてやめてた。

今回は最後まで読めた。

最後にかけて内容が尻すぼみ感かな。

星:★★★☆☆

(Spring Boot)Controller実装

package webapp.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import webapp.dao.WebAppDao;
import webapp.entity.Author;
import webapp.entity.Book;
import webapp.response.AuthorResponse;

@Controller
@RequestMapping(value = "/webapp")
public class WebAppController {
    
    @Autowired
    private WebAppDao dao;

    @RequestMapping(value = "/author", method = RequestMethod.GET)
    @ResponseBody
    public AuthorResponse author(@RequestParam String id) {
        
        int authorId = Integer.parseInt(id);
        
        // Author
        List<Author> authorList = dao.selectAuthor(authorId);
        
        // Books
        List<Book> bookList = dao.selectAuthorBooks(authorId);
        
        // Response
        AuthorResponse response = new AuthorResponse(
                authorList.get(0).getId(), 
                authorList.get(0).getName(), 
                authorList.get(0).getBirthDay(), 
                bookList);
        
        return response;
    }
}

アクセスは、 http://localhost:8080/webapp/author?id=2 です。

これで一連の Spring Boot & Doma2 を終了とする。


(Spring Boot)Spring Tools Suite(STS)のセットアップ

(Spring Boot)Doma2を使う準備

(Spring Boot)エンティティの準備

(Spring Boot)Dao実装

(Spring Boot)Responseオブジェクト

(Spring Boot)Controller実装