LoginSignup
0
3

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-11-10

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

今回作成したアプリ ==>久喜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でグローバルに参照できます。

1.Admin Component

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

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の以下のコードが効いています。再掲載していきます。

    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アプリ作成入門」を終わります。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3