AWS+Reactアプリ作成入門(ログイン後のAdmin編)

[AWS+Reactアプリ作成入門(Cognito編)](https://qiita.com/sand/items/e1f4ec830d13569a7128 "AWS+Reactアプリ作成入門(Cognito編)")
[AWS+Reactアプリ作成入門(S3編）](https://qiita.com/sand/items/94cd85c3c0426dc768bd "AWS+Reactアプリ作成入門(S3編）")
[AWS+Reactアプリ作成入門(DynamoDB編）](https://qiita.com/sand/items/70018f322d6fe986fe60 "AWS+Reactアプリ作成入門(DynamoDB編）")
[AWS+Reactアプリ作成入門(IAM Role編）](https://qiita.com/sand/items/a07a08f7c1ccc2e8b967 "AWS+Reactアプリ作成入門(IAM Role編）")
[AWS+Reactアプリ作成入門(ログイン後のAdmin編)](https://qiita.com/sand/items/260a6a0b360e574642cf "AWS+Reactアプリ作成入門(ログイン後のAdmin編)")


今回作成したアプリ ==>[久喜SNS](http://kuki-app-bucket.s3-website-ap-northeast-1.amazonaws.com/ "久喜SNS")

　AWS+Reactアプリ作成入門は今回で最後です。書き残したことで重要なところを書きたいと思います。

　今回特に難しかったところはCognitoの使い方でした。一通り「AWS+Reactアプリ作成入門(Cognito編)」に書きましたが、重要な点をまだ書いていません。Reactアプリは複数のComponentファイルから成り立っています。「AWS+Reactアプリ作成入門(Cognito編)」で示したApp Componentを参照してください。App.jsファイルがロードされたときに非ログインユーザとして権限を持ち、LoginView Componentでログインした時にログインユーザとしての権限を持つようになり、Admin ComponentでS3やDynamoDBに画像ファイルやドキュメントをputするわけです。明記しているドキュメントが見つからず、ログイン状態はAdmin.jsでもそのまま保持されるのかが疑問でした。いろいろ試行錯誤した結果、答えはYesです。
　LoginView Componentで一度ログインすれば、その他のComponentのプログラムはログインユーザとして動作します。ユーザIDはAWS.config.credentials.identityIdでグローバルに参照できます。


# １．Admin Component

　Admin Componentはログイン後にメニューに現れる管理画面で、画像掲示板の投稿・編集・削除を行う場所です。ログインユーザとしての権限を最大限に発揮できる画面です。特にCognito認証関係のコードを書かずに権限を実行できます。

```js:src/views/Admin.jsの一部
import AWS from "aws-sdk";
import React from 'react';

---

export default class Admin extends  React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {

---

  _fetch(identityId) {
    const _self = this;
    var dynamo = new AWS.DynamoDB.DocumentClient();
    var param = {
      TableName : tablename,
      ScanIndexForward: false, //queryには効くが、scanには効かない
      KeyConditionExpression : "identityId = :identityId",
      ExpressionAttributeValues : {":identityId" : identityId}
    };
    dynamo.query(param, function(err, data) {
        if (err) {
            console.log("### Error="+err);
        } else {
            //console.log("### data="+JSON.stringify(data.Items));
            _self.setState({items: data.Items});
        }
    });
  }

  componentWillMount() {
    const _self = this;
    const email = localStorage.getItem('email');
    const username = localStorage.getItem('username');
    var identityId = AWS.config.credentials.identityId;

    if( !email ) {
        handleErrorFunc('エラー：ログインしていません');
        return;
    }
    this.setState({identityId: identityId});
    this.setState({email: email});
    this.setState({username: username});
    this._fetch(identityId);
  }

---

  postAdd() {
    const _self = this;
    const identityId = _self.state.identityId;

//-------------------------------
// Date
//-------------------------------
    let uploadTime = 0;
    let uploadDate = "";
    let partitionYear = 0;
    if( !this.state.updateItem ) { //新規投稿
        const date = new Date() ;
        uploadTime = date.getTime();
        uploadDate = toLocaleString(date);
        partitionYear = date.getFullYear();
    } else {                        //編集投稿
        uploadTime = _self.state.updateItem.uploadTime;
        uploadDate = _self.state.updateItem.uploadDate;
        partitionYear = _self.state.updateItem.partitionYear;
    }


//-------------------------------
// S3 put
//-------------------------------
    let filepath = noimage;
    let thumbnail = noimage;
    let fileType = noimage;
    if( _self.state.imageOverwrite && !!_self.state.file) { 
        if (!_self.state.file.name.match(/^[0-9a-zA-Z\.\_\-]*$/)) {
            handleErrorFunc('エラー：ファイル名は小文字の英数字と . - _ しか使えません: '+_self.state.file.name );
            return;
        }
        filepath = 'contents/images/'+identityId+'/'+_self.state.file.name;
        thumbnail = filepath.replace(/images/, 'thumbnail');
        fileType = _self.state.file.type;
        console.log("filepath="+filepath);
        var params = {
            Bucket: bucketname,
            Key: filepath,
            ContentType: _self.state.file.type,
            Body: _self.state.file,
            Metadata: {
              data: JSON.stringify({
                identityId: identityId,
                uploadTime: uploadTime,
                uploadDate: uploadDate
              })
            }
        };
        var s3 = new AWS.S3();
        s3.putObject(params, function(err, data) {
            if(err) {
                console.log("Err: upload failed :" +err);
            } else {
                console.log("Success: upload ok");
                let url = 'http://'+bucketname+'.s3-'+appConfig.region+'.amazonaws.com/'+filepath;
                console.log("######11 imgurl="+url);
                _self.setState({imgurl: url});
            }
        });
    } else if ( _self.state.updateItem && !_self.state.imageOverwrite ) { //編集投稿で上書きアップロード無し
        filepath = _self.state.updateItem.filename;
        thumbnail = _self.state.updateItem.thumbnail;
        fileType = _self.state.updateItem.fileType;;    
    }
//-------------------------------
// DynamoDB putItem
//-------------------------------
    const title = escape_html(_self.state.title);
    let story = escape_html(_self.state.story);
    story = story.replace(/((http:|https:)\/\/[\x21-\x26\x28-\x7e]+)/gi, "<a href='$1'>$1</a>");


    var docClient = new AWS.DynamoDB.DocumentClient();
    var params = {
        TableName: tablename,
        Item:{
             identityId: identityId, // ★prime partition key
             email: _self.state.email,
             username: _self.state.username,
             filename: filepath,
             thumbnail: thumbnail,
             type: fileType,
             title: title,
             story: story,
             imageOverwrite: _self.state.imageOverwrite,
             mapUse: _self.state.mapUse,
             position: _self.state.position,
             uploadTime: uploadTime, // ★prime & secondary sort key
             uploadDate: uploadDate,
             partitionYear: partitionYear, //★secondary partition key
             refCounter: 0
        }
    };
    docClient.put(params, function(err, data) {
        if(err) {
            console.log("Err: table put :" +err);
        } else {
            console.log("Success: table put ok");
        }
    });

//-------------------------------
// Clear form
//-------------------------------
    this.handlePostNew();

    this._fetch(identityId);

  }

---


```

　LoginView Componentでログインしているので、このAdmin ComponentでもログインユーザとしてS3やDynamoDBにputする権限を持っています。一応念のためにcomponentWillMount()でログインしているかの確認をしています。localStorageにemailがセットされているか否かで判断しています。LoginView Componentの以下のコードが効いています。再掲載していきます。

```js
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: appConfig.IdentityPoolId,
        Logins : {
            // Change the key below according to the specific region your user pool is in.
            'cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxxx' : result.getIdToken().getJwtToken()
        }
    });
```



　見直しや、修正を入れること張りますが、以上で「AWS+Reactアプリ作成入門」を終わります。