[Golang]Cognito操作

## 注意

細かいエラー処理などはしていないのであくまでも参考程度にしてください。

ほとんどなぐり書きなので使う前にコードを整えてから使ってください。

## 共通の環境引数

- export CLIENTSECRET=
- export CLIENTID=
- export USERERPOOlID=

##ライブラリの全体像

![Screenshot 2022-11-29 at 02-27-20 cognitoauth - Go Documentation Server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681799/7122c124-5a23-3fc8-ae88-e3ee0948195e.png)


## ライブラリ

```golang:cognitoauth.go

package cognitoauth


import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"os"

	"github.com/aws/aws-sdk-go/aws"
	cognito "github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
)

type App struct {
	CognitoClient   *cognito.CognitoIdentityProvider
	UserPoolID      string
	AppClientID     string
	AppClientSecret string
}


func computeSecretHash(clientSecret string, username string, clientId string) string {
	mac := hmac.New(sha256.New, []byte(clientSecret))
	mac.Write([]byte(username + clientId))

	return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}

func (a *App) Set_ClientSecret(username string) {
	a.AppClientSecret = computeSecretHash(
		os.Getenv("CLIENTSECRET"),
		username,
		a.AppClientID,
	)
}

func (a *App) Set_ClientId() {
	a.AppClientID = os.Getenv("CLIENTID")
}

func (a *App) Set_UserPoolId() {
	a.UserPoolID = os.Getenv("USERPOOLID")
}

func (a *App) Set_Default(username string) {
	a.Set_ClientId()
	a.Set_UserPoolId()
	a.Set_ClientSecret(username)

}

func (a *App) Register(
	username string,
	password string,
	email string,
) {
	a.Set_ClientId()
	a.Set_ClientSecret(username)

	user := &cognito.SignUpInput{
		Username:   aws.String(username),
		Password:   aws.String(password),
		ClientId:   aws.String(a.AppClientID),
		SecretHash: aws.String(a.AppClientSecret),
		UserAttributes: []*cognito.AttributeType{
			{
				Name:  aws.String("email"),
				Value: aws.String(email),
			},
		},
	}

	_, err := a.CognitoClient.SignUp(user)
	if err != nil {
		fmt.Println(err)

		return
	}

}

func (a *App) ActivateUser(username string, otp string) {
	// func (c *CognitoIdentityProvider) ConfirmSignUp(input *ConfirmSignUpInput) (*ConfirmSignUpOutput, error)

	a.Set_ClientId()
	a.Set_ClientSecret(username)

	// usernameをpre-session-cookieでDynamoから取得する
	user := &cognito.ConfirmSignUpInput{
		ConfirmationCode: aws.String(otp),
		Username:         aws.String(username),
		ClientId:         aws.String(a.AppClientID),
		SecretHash:       aws.String(a.AppClientSecret),
	}
	fmt.Println("")

	_, err := a.CognitoClient.ConfirmSignUp(user)
	if err != nil {

		fmt.Println(err)
		return
	}

}




```


## 会員登録

### フロントからの入力
- username
- password(できれば２回入力させてチェック)
- email

```golang:cognito_test.go

func TestRegistration(t *testing.T) {

	var username = ""
	var password = ""
	var email = ""

	// AWSの認証
	conf := &aws.Config{Region: aws.String("ap-northeast-1")}
	// AWSとの新規セッションを作成
	sess, err := session.NewSession(conf)

	// session作成をが失敗したときのエラー処理
	if err != nil {
		panic(err)
	}
	// cognitoのインスタンスを作成する
	example := App{
		CognitoClient: cognito.New(sess),
	}

	//user登録をする
	example.Register(
		username,
		password,
		email,
	)

}

```

## 会員登録をしたユーザーの有効化

```golang:cognito_test.go

func TestActivateUser(t *testing.T) {
	// AWSの認証
	conf := &aws.Config{Region: aws.String("ap-northeast-1")}
	// AWSとの新規セッションを作成
	sess, err := session.NewSession(conf)

	var username string = ""
	var otp string = ""

	// session作成をが失敗したときのエラー処理
	if err != nil {
		panic(err)
	}

	// cognitoのインスタンスを作成する
	example := App{
		CognitoClient: cognito.New(sess),
	}

	// 登録後の有効化
	example.ActivateUser(username, otp)
}

```

## ログイン

## ログイン専用ページの処理

## ログアウト